5

如何将函数参数分配给具有完全相同名称的全局变量?

注意: 我不能这样做self.myVariable = myVariable,因为我的函数不在类中。

编写以下代码时,我收到一条错误消息,提示“参数既是本地的又是全局的”。

myVar = 1
def myFunction(myVar):
    global myVar

这是不可能的吗?如果是这样,在其他语言中是否不常见?来自我习惯的javathis.myVar = myVar

编辑我已经知道我可以重命名变量。这是最简单的出路。

4

3 回答 3

7

最佳解决方案:重构您的代码。重命名某些东西,或者使用具有对象属性的对象而不是全局变量。

替代,hacky 解决方案:直接修改全局变量 dict :

my_var = 1
def my_function(my_var):
    globals()['my_var'] = my_var
于 2013-07-11T19:12:19.480 回答
1

最好(也是最快)的事情是采取简单的方法并重命名变量。但是,如果您坚持,您可以通过以下方式解决命名冲突:

import sys
_global = sys.modules[__name__]
# or _globals = sys.modules[__name__].__dict__

myVar = 1
def myFunction(myVar):
    _global.myVar = myVar  # or _globals['myVar'] = myVar

print myVar  # 1
myFunction(42)
print myVar  # 42

解释:

在模块中,模块的名称(作为字符串)可用作全局变量的值__name__。该名称sys.modules是指将模块名称映射到已加载的模块的字典。如果myFunction()正在运行,它的模块已经被加载,所以那个时候sys.modules[__name__]是它定义的模块。由于全局变量MyVar也在模块中定义,因此可以使用sys.modules[__name__].myVar. (为了使其用法类似于 java,你可以命名它this——但我个人认为_global更好。)

此外,由于模块的只读__dict__属性是它的命名空间——也就是全局命名空间——表示为字典对象,sys.modules[__name__].__dict__是另一种引用它的有效方式。

请注意,在任何一种情况下,如果对不存在的名称进行分配,都会创建新的全局变量——就像使用global关键字一样。

于 2013-07-11T20:01:09.820 回答
1

答案是欺骗 Python 去做。在您的代码中:

myVar = 1
def myFunction(myVar):
    global myVar

myFunction 永远不会运行(你永远不会调用它)。因此,脚本永远不会到达global myVar重点。然而,由于某种原因,Python 仍然爆炸了。我相信那是因为它被告知“不允许这样做”。无论如何,你可以欺骗它做你想做的事。一种没有被建议的方法是在 myFunction 中使用一个简单的函数:

myVar = 1
def myFunction(myVar):
    def trick(arg):
        global myVar
        myVar = arg
    trick(myVar)

print myVar # Comes back with 1
myFunction(22)
print myVar # Comes back with 22

可能不在一行,但您不必导入任何内容,并且更易于阅读。

于 2013-07-11T21:10:57.863 回答