2012-12-03 70 views
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() 

是一個這樣的函數嗎?

+2

你不應該使用'eval ()'這樣的事情 - 這是一個不好的方法。看看'getattr()'。 –

+1

對Lattyware的評論+1。另外,您可能想要使用'inspect'模塊而不是手動迭代'dir'並確定如何處理它。 – abarnert

+0

這些都是很好的建議,但真正的問題是訪問函數名稱空間外的對象。 – alex

回答

1

如果我定義爲一個函數,或者把它放在別的地方,比如在mymodule中,那麼dir()命令不會返回當前命名空間,而是函數所看到的命名空間。即使我將dir()的結果作爲參數傳遞,對象在函數中也不可用。

對,這是因爲您使用eval來評估它們,它們在當前命名空間中對它們進行評估。您可能通過來自不同主空間的globalslocals,並用這些參數調用eval。換句話說,不是foo(dir()),而是foo(dir(),globals(),locals())`。

但是,這整個設計是一個壞主意。使用eval來獲得範圍的成員是一個壞主意。其實eval幾乎用於什麼東西是個不錯的主意。

一個更好的解決方案是將想要評估成員的東西通過,並使用getattr來獲取它們。

而更好的解決方案是避免使用dir,然後弄清楚如何獲得這些名稱的屬性;如果你想檢查的東西,這就是inspect模塊的用途。 (即使你想做一些inspect不完全提供的東西,閱讀它的源代碼 - 從文檔鏈接 - 通常會告訴你最好的方法來做到這一點)。

+0

傳遞'locals()'的輸出解決名稱空間問題,而'inspect'模塊確實是usefule在確定源模塊。 – alex

相關問題