【发布时间】:2012-11-21 08:03:29
【问题描述】:
我想编写一个函数来腌制当前命名空间中的所有对象,这些对象是给定模块中类的实例。这个想法是,在 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()
这样的功能可行吗?
【问题讨论】:
-
你不应该使用
eval()来做这样的事情——这是一种糟糕的方法。看看getattr()。 -
+1 对 Lattyware 的评论。此外,您可能希望使用
inspect模块,而不是手动迭代dir并弄清楚如何处理它。 -
这些都是很好的建议,但真正的问题是访问函数命名空间之外的对象。
-
@alex:你需要引用那个命名空间。一旦你有了它,你就可以使用
inspect或getattr来访问其中的对象。如果你没有它,但你有一些东西可以用来访问它(例如,你可以用sys.modules[name]查找的模块的名称),或者足以伪造它(globals()和locals()从该命名空间调用),也可以。但除此之外,没有办法访问这些对象,也没有任何办法可以提供帮助。 (如果您来自 JS,Python 没有作为默认上下文的全局window对象。)
标签: python namespaces scope ipython pickle