用于从给定模块中挑选所有对象的功能

时间:2012-12-03 19:32:15

标签: python namespaces scope ipython pickle

我想编写一个函数来挑选当前命名空间中的所有对象,这些对象是给定模块中的类的实例。我们的想法是,在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()

是这样的功能吗?

1 个答案:

答案 0 :(得分:1)

  

如果我定义为一个函数,或者把它放在其他地方,就像在mymodule中一样,那么dir()命令不会返回当前的命名空间,而是返回函数所看到的命名空间。即使我将dir()的结果作为参数传递,对象也不能在函数中使用。

是的,那是因为您正在使用eval来评估它们,它们会在当前命名空间中对它们进行评估。您可以从另一个主空间传递globalslocals,并使用这些参数调用eval。换句话说,而不是foo(dir()),foo(dir(),globals(),locals())`。

然而,这整个设计是一个坏主意。使用eval获取范围的成员是一个坏主意。事实上,使用eval几乎任何是一个坏主意。

更好的解决方案是传递您想要评估其成员的内容,并使用getattr来获取它们。

更好的解决方案是避免使用dir,然后弄清楚如何使用这些名称获取属性;如果你想检查事物,那就是inspect模块的用途。 (即使你想做一些inspect没有提供的东西,阅读它的源代码 - 从文档中链接 - 通常会告诉你最好的方法。)