問題描述
如何在 python 中修改函數的本地命名空間?我知道 locals() 在函數內部調用時會返回函數的本地命名空間,但我想做這樣的事情(我有一個理由要在 f 無法訪問 g 的情況下執行此操作,但給出更快一個簡單的、愚蠢的例子來說明問題):
How can I modify the local namespace of a function in python? I know that locals() returns the local namespace of the function when called inside it, but I want to do something like this (I have a reason why I want to do this where g is not accessible to f, but it's quicker to give a trivial, stupid example to illustrate the problem):
def g():
pass
def f():
g()
f.add_to_locals({'g':g})
推薦答案
你有幾個選擇.首先,請注意,您的示例中的 g 實際上并不是函數的局部變量(即未在其中分配),它是全局變量(即尚未分配給局部變量).這意味著它將在定義函數的模塊中查找它.這是幸運的,因為沒有辦法在外部更改本地變量(除了修補字節碼),因為它們是在函數運行時分配的,而不是之前.
You've a couple of options. First, note that g in your example isn't actually a local to the function (ie. not assigned within it), it's a global (ie hasn't been assigned to a local variable). This means that it will be looked up in the module the function is defined in. This is fortunate, as there's no way of altering locals externally (short of patching the bytecode), as they get assigned when the function runs, not before.
一種選擇就是將你的函數注入到函數模塊的命名空間中.這將起作用,但會影響該模塊中訪問變量的每個函數,而不僅僅是一個函數.
One option is simply to inject your function into the function's module's namespace. This will work, but will affect every function in that module that accesses the variable, rather than just the one function.
要只影響一個函數,您需要將 func_globals 指向其他地方.不幸的是,這是一個只讀屬性,但您可以通過使用相同的主體但不同的全局命名空間重新創建函數來做您想做的事情:
To affect just the one function, you need to instead point that func_globals somewhere else. Unfortunately, this is a read-only property, but you can do what you want by recreating the function with the same body, but a different global namespace:
import new
f = new.function(f.func_code, {'g': my_g_function}, f.func_name, f.func_defaults, f.func_closure)
f 現在將是相同的,除了它將在提供的 dict 中查找全局變量.請注意,這會重新綁定整個全局名稱空間 - 如果那里有 f 確實 查找的變量,請確保您也提供它們.不過,這也相當 hacky,并且可能不適用于 cpython 以外的 python 版本.
f will now be indentical, except that it will look for globals in the provided dict. Note that this rebinds the whole global namespace - if there are variables there that f does look up, make sure you provide them too. This is also fairly hacky though, and may not work on versions of python other than cpython.
這篇關于如何在python中修改本地命名空間的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!