Globals作为函数输入而不是参数

时间:2013-04-25 12:06:05

标签: python

我只是在学习Python是如何工作的,在阅读了一段时间后,我仍然对全局变量和正确的函数参数感到困惑。考虑案例全局变量未在函数内修改,仅引用。

可以使用全局变量而不是函数参数吗? 我听说使用全局变量被认为是一种不好的做法。在这种情况下会这样吗?

不带参数调用函数:

def myfunc() :
    print myvalue

myvalue = 1
myfunc()

使用参数调用函数

def myfunc(arg) :
    print arg

myvalue = 1
myfunc(myvalue)

4 个答案:

答案 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更好的原因有几个:

  1. 它消除了可能的混淆:一旦你的程序变大,跟踪在哪里使用哪个全局变得非常困难。传递函数参数可以让您更清楚函数使用哪些值。
  2. 如果你使用全局变量,你最终会犯一个特别的错误,在你明白发生了什么之前,它会看起来非常奇怪。它与在同一函数中修改和读取全局变量有关。稍后会详细介绍。
  3. 全局变量都存在于同一名称空间中,因此您很快就会遇到名称重叠的问题。如果您想要两个名为“index”的不同变量怎么办?调用它们index1index2将会变得非常混乱,真正快速。使用局部变量或函数参数意味着它们都存在于不同的命名空间中,并且大大减少了混淆的可能性。
  4. 现在,我提到在同一个函数中修改和读取全局变量,以及可能导致的混乱错误。这是它的样子:

    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

    这将首先实现您的预​​期。但希望你现在明白为什么它会起作用,而另一个版本则不行。