【发布时间】:2019-07-11 14:38:44
【问题描述】:
我在 python 3.7 中使用 dill,但是当我稍后重新加载它时,函数的属性之一丢失了。
我有一个名为 session 的类,我在程序退出时保存,在启动时加载。此对象间接包含Tranform 实例,这些实例具有引用特定函数的function 属性。该函数设置了几个属性。
当我在保存会话时使用调试器时,我可以看到特定属性存在并设置为None。但是当我加载一个保存的会话时,一切都很好,只是这个属性消失了。
这是保存代码:
def save(self):
print ('\n SAVING SESSION STATE, DO NOT EXIT')
breakpoint()
sessionDirectory='__PETL__'
if not os.path.exists(sessionDirectory):
os.makedirs(sessionDirectory)
with open(sessionDirectory+'/'+self.name, 'wb') as f:
dill.dump(self,f)
print ('\nSession Saved, exiting')
这是加载代码:
def loadSession(self, sessionName):
if (Session.dontLoad):
print ('Creating New Session')
return None
try:
with open('__PETL__/'+ sessionName, 'rb') as f:
session=dill.load(f)
except FileNotFoundError:
print ('No session found, creating new one')
return None
return session
这里是调试器的输出:
保存:
> /home/osboxes/stage/inspireDataBase2/migrations/src/session/session.py(160)save()
-> sessionDirectory='__PETL__'
(Pdb) print( self.transforms[0].transform.function.queryRes)
None
(Pdb) print (dir(self.transforms[0].transform.function)[-9:])
['after', 'args', 'columns', 'fetch', 'indexs', 'query', 'queryRes', 'sameorderasafter', 'transformvar']
(Pdb) dill.dumps(self.transforms[0].transform.function)
b'\x80\x03cuserTransformModulePreparsed\ntransform__constru__buildinggeometry2d\nq\x00.'
(Pdb) c
Session Saved, exiting
加载中:
> /home/osboxes/stage/inspireDataBase2/migrations/src/session/session.py(39)__init__()
-> session.printJobDone()
(Pdb) print( self.transforms[0].transform.function.queryRes)
*** AttributeError: 'function' object has no attribute 'queryRes'
(Pdb) print( session.transforms[0].transform.function.queryRes)
*** AttributeError: 'function' object has no attribute 'queryRes'
(Pdb) print (dir(session.transforms[0].transform.function)[-9:])
['__subclasshook__', 'after', 'args', 'columns', 'fetch', 'indexs', 'query', 'sameorderasafter', 'transformvar']
如您所见,其他属性按预期工作。
由于保存部分是我在项目中做的最后一件事,我想我只是不明白 dill 是如何工作的。该属性与另一个不同,因为该属性是在另一个类中设置的(与函数不在同一个模块中)。其他属性直接在函数的模块中设置。这就是说,模块是通过编译一个AST树获得的,但我不明白为什么会出现问题。
而且我看到确实在第一个输出中,在 dill 输出中只有对函数模块的引用(但我不知道 dill 是如何工作的,也许这是正常的)。
【问题讨论】:
-
这些属性通常是如何设置的?我强烈怀疑您看到的“已恢复”属性实际上是在您导入模块时设置的(或者在启动和运行
dill.load()之间的某个其他时间点已经在函数对象上设置)。提示:调试函数属性时,请使用sorted(vars(func))(仅属性名称)或vars(func)(完整属性字典),而不是dir()。后者添加了所有函数可用的属性。 -
请马丁给点小费!我将编辑问题以回答您的问题。
标签: python python-3.x pickle dill