1

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

这样的功能可能吗?

4

1 回答 1

1

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

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

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

A much better solution is to pass the thing you want to evaluate the members of, and use getattr to get them.

And an even better solution is to avoid using dir and then figuring out how to get the attributes with those names; if you want to inspect things, that's what the inspect module is for. (And even when you want to do something that inspect doesn't quite offer, reading its source code—which is linked from the docs—will usually tell you the best way to do it.)

于 2012-12-03T20:24:07.533 回答