jog*_*ran 15 python variables scope
我可以定义一个函数,在调用时,将新的本地插入到调用者的范围中吗?我有一种感觉,将调用者的locals()传递给函数可能会有效,但有没有办法做我想要的而不必这样做?
Pyk*_*ler 18
这段代码应该完全符合你的要求:
import inspect
def mess_with_caller():
stack = inspect.stack()
try:
locals_ = stack[1][0].f_locals
finally:
del stack
locals_['my_new_function'] = lambda : 'yaaaaaay'
mess_with_caller()
print my_new_function()
>>> Output: 'yaaaaaay'
Run Code Online (Sandbox Code Playgroud)
根据Python的规则,你无法改变你的来电者locals; 在当前的实现中,如果你尝试(例如使用黑魔法Anurag建议)你将不会得到异常(虽然我想将错误检查添加到未来的某个版本),但如果你的调用者是,那么它将基本上不起作用一个函数(如果你的调用者是模块顶级代码) - 调用者的实际局部变量实际上不会受到影响.这可以确定调用者locals是明确传入还是通过黑魔法获取:如果您的代码具有任何理智,它们仍然需要被视为只读字典.
相反,您可以让调用者通过一个明确的,真实的,正常的dict(可以根据需要进行初始化locals()),并且您的代码在该dict中所做的所有更改仍将存在于调用者的使用中 - 只是不是"新barenames"当然在调用者的局部范围内,但功能是调用者是否需要使用相同x['foo']或x.foo或(如您愿意)刚刚barename foo.
顺便说一下,要使用属性访问语法而不是dict索引语法,你可以这样做:
class Bunch(object): pass
...
# caller code
b = Bunch()
thefun(b)
print b.foo
...
# called function
def thefun(b):
b.foo = 23
Run Code Online (Sandbox Code Playgroud)
这还包括一个微小的变化,在这种情况下,thefun希望使用dict索引语法(比如它的主体b['foo'] = 23代替b.foo = 23):在这种情况下,调用者只需要使用thefun(vars(b))而不是普通thefun(b),但它可以继续使用b.foo之后的访问语法.
| 归档时间: |
|
| 查看次数: |
3382 次 |
| 最近记录: |