假设我有两个模块:
py
value = 3 def x() return value
b.py
from a import x value = 4
我的目标是使用a.xin的功能b,但更改该函数返回的值。具体来说,即使我运行,value也将其查找a为全局名称的来源b.x()。我基本上是在尝试创建功能对象的副本,该副本与之b.x相同a.x但用于b获取其全局变量。是否有合理而直接的方法?
a.x
b
value
a
b.x()
b.x
这是一个例子:
import a, b print(a.x(), b.x())
结果是当前3 3,但我希望如此3 4。
3 3
3 4
我想出了两种可行的复杂方法,但是我对其中任何一种都不满意:
x
def x(value): return value
这给我要避免的用户增加了负担,并不能真正解决问题。
有没有办法修改该函数以某种方式获取其全局变量的位置?
我已经通过猜测和检查以及研究的结合提出了一个解决方案。您几乎可以完全按照我在问题中的建议进行操作:复制函数对象并替换其__globals__属性。
__globals__
我正在使用Python 3,因此这是上面链接的问题的答案的修改后的版本,带有一个覆盖全局变量的附加选项:
import copy import types import functools def copy_func(f, globals=None, module=None): """Based on https://stackoverflow.com/a/13503277/2988730 (@unutbu)""" if globals is None: globals = f.__globals__ g = types.FunctionType(f.__code__, globals, name=f.__name__, argdefs=f.__defaults__, closure=f.__closure__) g = functools.update_wrapper(g, f) if module is not None: g.__module__ = module g.__kwdefaults__ = copy.copy(f.__kwdefaults__) return g
from a import x value = 4 x = copy_func(x, globals(), __name__)
该__globals__属性是只读的,因此必须将其传递给的构造函数FunctionType。__globals__现有功能对象的引用不能更改:为什么func .__ globals__被记录为只读?。
FunctionType