它不是很Python,但如果你真的必須:import inspect
def compact(*names):
caller = inspect.stack()[1][0] # caller of compact()
vars = {}
for n in names:
if n in caller.f_locals:
vars[n] = caller.f_locals[n]
elif n in caller.f_globals:
vars[n] = caller.f_globals[n]
return vars
def extract(vars):
caller = inspect.stack()[1][0] # caller of extract()
for n, v in vars.items():
caller.f_locals[n] = v # NEVER DO THIS - not guaranteed to work
我已經使用了這些實作很多次,而且它們都是有效的,但是技術上不支援修改f_locals。
不過,說真的,如果你真的覺得有必要使用這些函數,那麼你很可能做錯事了。它似乎至少在三個方面與Python's philosophy背道而馳:“顯式優于隐式”,“簡單優于複雜”,“如果實作很難解釋,那是個壞主意”,或者更多(而且,如果你在Python方面有足夠的經驗,你知道這樣的事情還沒有完成)。我可以看到它對于調試器或事後分析非常有用,或者對于某種非常通用的架構,它經常需要用動态選擇的名稱和值建立變量,但這是一個擴充。
如果要使用這些函數,至少應該将extracted變量包含在小範圍内。将它們包裝在函數中,然後可以将其視為“黑盒”。extract不好的主要原因是,它将變量放在符号表中的方式在檢查代碼時并不清楚。如果您将這些變量的效果局限于一個非常小的函數,并解釋清楚代碼和注釋的用途,那就不是什麼大問題。