我想编写一个函数来挑选当前命名空间中的所有对象,这些对象是给定模块中的类的实例。我们的想法是,在ipython会话期间,用户会从mymodule
创建许多对象,并且可能需要快速保存所有对象。
所以,例如我想要这样的东西
from mymodule import cat, dog, pickle_all
c= cat(), d=dog()
pickle_all('killer_sesh.p')
结束会话,忘记一个月,回来开始新会议,
from mymodule import upickle_all
objs = unpickle_all('killer_sesh.p')
所以我的第一次尝试(如下所示)在粘贴到当前命名空间时有效。如果我定义为一个函数,或者把它放在其他地方,比如在mymodule中,那么dir()
命令不会返回当前的命名空间,而是返回函数所看到的命名空间。即使我将dir()的结果作为参数传递,该对象在函数中也不可用。
import pickle
filename= 'killer_sesh.p'
module='mymodule'
module_objects = {}
for k in dir():
try:
if eval(k).__module__.split('.')[0] == module:
if k[0]!='_':
print(k)
module_objects[k] = eval(k)
except(AttributeError):
pass
file= open(filename,'w')
pickle.dump(module_objects, file)
file.close()
是这样的功能吗?
答案 0 :(得分:1)
如果我定义为一个函数,或者把它放在其他地方,就像在mymodule中一样,那么dir()命令不会返回当前的命名空间,而是返回函数所看到的命名空间。即使我将dir()的结果作为参数传递,对象也不能在函数中使用。
是的,那是因为您正在使用eval
来评估它们,它们会在当前命名空间中对它们进行评估。您可以从另一个主空间传递globals
和locals
,并使用这些参数调用eval
。换句话说,而不是foo(dir())
,foo(dir(),globals(),locals())`。
然而,这整个设计是一个坏主意。使用eval
获取范围的成员是一个坏主意。事实上,使用eval
几乎任何是一个坏主意。
更好的解决方案是传递您想要评估其成员的内容,并使用getattr
来获取它们。
更好的解决方案是避免使用dir
,然后弄清楚如何使用这些名称获取属性;如果你想检查事物,那就是inspect模块的用途。 (即使你想做一些inspect
没有提供的东西,阅读它的源代码 - 从文档中链接 - 通常会告诉你最好的方法。)