我在python3.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
不捕获函数属性,不捕获可直接导入的函数。加载时看到的任何属性都是由其他代码添加到函数对象的,可能是在导入时所有
dill.dumps()
存储的信息都足以重新导入相同的函数对象;在调试会话中,这是userTransformModulePreparsed.transform__constru__buildinggeometry2d
。加载序列化时,需要做的就是import userTransformModulePreparsed
,然后使用该模块的transform__constru__buildinggeometry2d
属性。函数被视为单例在这种情况下,每个Python进程只需要存在一个副本。假设该对象的所有加载都由正常的import
进程处理。这包括添加到函数对象的属性dill
可以处理生成的函数对象,即任何不能直接导入的函数对象,此时它将捕获函数的所有方面,包括属性。例如,每次调用父函数时,在函数(嵌套函数)内部使用def
总是会创建一个新的、单独的函数对象。序列化此类对象的处理方式不同:所以你有两个选择;在导入时设置函数属性,或在嵌套函数中生成函数
相关问题 更多 >
编程相关推荐