1

特定のモジュールのクラスのインスタンスである現在の名前空間内のすべてのオブジェクトをピクルする関数を書きたいと思います。アイデアは、ipython セッション中にユーザーが から多くのオブジェクトを作成しmymodule、それらすべてをすばやく保存する必要がある場合があるということです。

だから、例えば、私はこのようなものが欲しい

from mymodule import cat, dog, pickle_all
c= cat(), d=dog()
pickle_all('killer_sesh.p')

セッションを終了し、1 か月間忘れて、戻ってきて新しいセッションを開始し、

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それらを評価するために使用しているからです。それは現在の名前空間でそれらを評価します。別のメインスペースからとを渡し、それらのパラメーターを使用して呼び出すことができます。つまり、foo(dir()、globals()、locals())`の代わりに。globalslocalsevalfoo(dir())

ただし、この全体の設計は悪い考えです。evalスコープのメンバーを取得するために使用することは悪い考えです。実際、evalほとんどすべてに使用することは悪い考えです。

はるかに優れた解決策は、メンバーを評価したいものを渡し、それらを取得するために使用getattrすることです。

dirそして、さらに良い解決策は、それらの名前で属性を取得する方法を使用して理解することを避けることです。物事を検査したい場合は、それが検査モジュールの目的です。(そして、まったく提供されていないことをしたい場合でもinspect、ドキュメントからリンクされているソースコードを読むと、通常、それを行うための最良の方法がわかります。)

于 2012-12-03T20:24:07.533 に答える