如何在python中修改本地名称空间

2024-03-29 08:29:34 发布

您现在位置:Python中文网/ 问答频道 /正文

如何在python中修改函数的本地命名空间?我知道local s()在函数内部调用时返回函数的本地名称空间,但我想这样做(我有一个原因,为什么要在f无法访问g的情况下这样做,但给出一个简单、愚蠢的示例来说明问题会更快):

def g():
   pass

def f():
    g()

f.add_to_locals({'g':g})

Tags: to函数名称add示例localdef空间
3条回答

由于函数没有被调用,它还没有“本地”堆栈帧。最简单的解决方案是使用全局上下文:

handler = None
def f():
    handler()

def g(): pass

handler = g

或者可以在函数对象上设置g:

f.g = g

但我不确定如何从函数内部获取函数对象。如果这是一种方法,您可以使用self

为什么不向f()添加一个参数并传递对g()的引用呢?

def g():
    pass

def f(func):
    func()

f(g)

你有两个选择。首先,注意在你的例子中,g实际上不是函数的局部(即没有在函数中赋值),它是全局的(即没有被赋值给局部变量)。这意味着它将在定义函数的模块中查找。这是幸运的,因为没有办法在外部更改局部变量(除了修补字节码),因为它们是在函数运行时分配的,而不是以前。

一种方法是简单地将函数注入函数的模块名称空间。这将起作用,但将影响该模块中访问变量的每个函数,而不仅仅是一个函数。

要只影响一个函数,您需要将该函数指向其他地方。不幸的是,这是一个只读属性,但是您可以通过重新创建具有相同主体但具有不同全局命名空间的函数来完成所需的操作:

import new
f = new.function(f.func_code, {'g': my_g_function}, f.func_name, f.func_defaults, f.func_closure)

f现在是缩进的,只是它将在提供的dict中查找全局变量。注意,这将重新绑定整个全局命名空间-如果有f查找的变量,请确保您也提供了它们。不过,这也相当老套,除了cpython之外,可能无法在python版本上工作。

相关问题 更多 >