我只是在学习Python是如何工作的,在阅读了一段时间后,我仍然对全局变量和正确的函数参数感到困惑。考虑案例全局变量未在函数内修改,仅引用。
可以使用全局变量而不是函数参数吗? 我听说使用全局变量被认为是一种不好的做法。在这种情况下会这样吗?
不带参数调用函数:
def myfunc() :
print myvalue
myvalue = 1
myfunc()
使用参数调用函数
def myfunc(arg) :
print arg
myvalue = 1
myfunc(myvalue)
答案 0 :(得分:2)
我听说使用全局变量被认为是一种不好的做法。在这种情况下会这样吗?
这取决于你想要达到的目标。如果myfunc()
应该打印任何值,那么......
def myfunc(arg):
print arg
myfunc(1)
...更好,但如果myfunc()
应始终打印相同的值,那么......
myvalue = 1
def myfunc():
print myvalue
myfunc()
...更好,虽然有一个例子如此简单,你也可以将全局分解出来,只需使用......
def myfunc():
print 1
myfunc()
答案 1 :(得分:0)
是。使变量global
适用于这些情况,而不是将它们作为函数参数传递。但是,问题在于,一旦开始编写更大的函数,就会很快耗尽名称,并且很难维护全局定义的变量。如果您不需要编辑变量并且只想阅读它,则无需在函数中将其定义为global
。
在这里阅读全局变量的缺点 - Are global variables bad?
答案 2 :(得分:0)
这取决于你想做什么。
如果需要更改在函数外部声明的变量的值,则不能将其作为参数传递,因为这会在函数范围内创建该变量的“副本”。
但是,如果您只想使用变量的值,则应将其作为参数传递。这样做的好处是你不会意外地弄乱全局变量。
此外,您应该在使用全局变量之前声明它们。
答案 3 :(得分:0)
使用函数参数比使用globals更好的原因有几个:
index1
和index2
将会变得非常混乱,真正快速。使用局部变量或函数参数意味着它们都存在于不同的命名空间中,并且大大减少了混淆的可能性。现在,我提到在同一个函数中修改和读取全局变量,以及可能导致的混乱错误。这是它的样子:
record_count = 0 # Global variable
def func():
print "Record count:", record_count
# Do something, maybe read a record from a database
record_count = record_count + 1 # Would normally use += 1 here, but it's easier to see what's happening with the "n = n + 1" syntax
这将失败:UnboundLocalError: local variable 'record_count' referenced before assignment
record_count
被视为局部变量,当它显然是全局的?好吧,如果您从未在函数中分配到record_count
,那么Python将使用全局变量。但是当你为record_count
赋值时,Python必须猜测你的意思:是否要修改全局变量,或者是否要创建一个阴影(隐藏)全局变量的新局部变量,以及只处理局部变量。并且Python将默认假设您对全局变量很聪明(即,在不知道完全您正在做什么以及为什么这样做的情况下不修改它们),并假设您打算创建一个新的局部变量名为record_count
。
但是如果你在函数中访问一个名为record_count
的局部变量,那么Python将不允许你在函数内部访问具有相同名称的全局变量。这是为了免除你一些真正讨厌的,难以追踪的错误。这意味着如果此函数具有名为record_count
的 local 变量 - 并且由于赋值语句而具有 - 那么所有访问{{1被认为是访问局部变量。 在定义局部变量值之前,在record_count
语句中包含访问权限。因此,print
例外。
现在,为读者练习。删除print语句,注意UnboundLocalError
异常仍然抛出。你能搞清楚为什么吗? (提示:在分配变量之前,必须计算分配右侧的值。)
现在:如果确实想在你的函数中使用全局UnboundLocalError
变量,那么使用Python的record_count
语句就是这样说的,“嘿,我将要指定的这个变量名?不要把它变成局部变量,即使我赋予它。分配给全局变量。“它的工作方式只是global
(或任何其他变量名),在函数的开头。因此:
global record_count
这将首先实现您的预期。但希望你现在明白为什么它会起作用,而另一个版本则不行。