Python:从函数参数中修改全局var



我想创建一个函数,根据传递给它的参数修改初始化的全局变量,但我得到了SyntaxError: name 'arg' is local and global。我已经看到了其他实现这一点的方法,使用globals()或在myFunc中创建一个简单的函数来"欺骗"Python。另一种方法是在myFunc中创建if语句来显式分配相应的全局变量,但这似乎过于冗长。

为什么会发生这种情况,最有效/优雅/Python的方法是什么?

给定:

var1 = 1
var2 = 2
var3 = 3
def myFunc(arg):
global arg
arg = 10
myFunc(var1) # each of these should print to 10
myFunc(var2)
myFunc(var3)

您可以使用globals()访问变量并从myFunc()中分配新值

var1 = 1
var2 = 2
def myFunc(varname):
globals()[varname] = 10
print(var1, var2)
myFunc("var1")
myFunc("var2")
print(var1, var2)

将输出:

1, 2
10, 10

在python中,变量是对象的名称。当你调用一个函数并向它传递一个参数时,你传递的是与变量相关的对象,而不是名称。例如,当你调用wash(mydog)时,你说的是"清洗被称为mydog的对象"。请记住,同一个对象可以有多个名称,例如spot = mydog = best_dog_ever = new_dog()。函数不知道用哪个名称传递对象,即使知道了,如果使用的名称不是全局范围内的名称,你也必须用某种方式来表示这个函数只接受全局变量作为参数。

我希望这有助于解释为什么你会出现语法错误,但你仍然可以通过至少两种方式完成几乎相同的事情。第一种是简单地将返回值分配给您试图更改的变量,例如:

var1 = 1
var2 = 2
def addone(a):
return a + 1
def main():
global var1, var2
var1 = addone(var1)
var2 = addone(var2)
print var1, var2
main()
print var1, var2

第二种方法是使用更面向对象的方法,类似于这样的方法:

class GlobalValue(object):
def __init__(self, value):
self.value = value
var1 = GlobalValue(1)
var2 = GlobalValue(2)
def addone(a):
a.value += 1
print var1.value, var2.value
addone(var1)
addone(var2)
print var1.value, var2.value

甚至更好:

class GlobalValue(object):
def __init__(self, value):
self.value = value
def addone(self):
self.value += 1
var1 = GlobalValue(1)
var2 = GlobalValue(2)
print var1.value, var2.value
var1.addone()
var2.addone()
print var1.value, var2.value

为什么会发生

因为要使用的全局变量与参数arg同名。在Python中,参数是局部变量,并且一个变量只能是局部变量或全局变量,而不能同时是局部变量和全局变量。

似乎您希望能够使用var的内容来指定要修改的现有全局变量。它不是那样工作的。首先,变量不包含其他变量;它们包含。变量的名称不是值。同样,参数是局部变量,调用函数会分配给这些变量。它指定一个。(请记住,您可以很容易地调用函数,而不使用参数myFunc(3)的变量。这是否会导致3以某种方式等于10?)

其次,即使您传递了一个字符串,也必须做更多的工作才能访问相应的全局变量。这是可以做到的,但请不要

实现这一点的最有效/最优雅/最Python的方法是什么?

Python的方式是不要。如果您希望函数在调用时传递信息,返回一个值

def myFunc():
return 10
var1 = myFunc()
var2 = myFunc()
var3 = myFunc()

修复错误的最简单方法是重命名全局变量。然而,这并不能修复代码的明显意图:

var1 = 1
var2 = 2
var3 = 3
def myFunc(arg):
global g
g = 10
# var1, var2 and var3 will NOT CHANGE
# Instead, the new global variable g is created, and assigned a value of 10,
# three times in a row.
myFunc(var1)
myFunc(var2)
myFunc(var3)

最新更新