谁能帮我理解Python变量范围?

i l*_*low 1 python function

我写了一个看起来像这样的测试程序:

#!/usr/bin/python

def incrementc():
    c = c + 1

def main():
    c = 5
    incrementc()

main()

print c
Run Code Online (Sandbox Code Playgroud)

我认为,因为我在main的主体内调用了incrementc,所以main中的所有变量都会传递给incrementc.但是当我运行这个程序时,我得到了

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    main()
  File "test.py", line 8, in main
    incrementc()
  File "test.py", line 4, in incrementc
    c = c + 1
UnboundLocalError: local variable 'c' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

为什么c不通过?如果我想让一个变量被多个函数引用,我是否必须全局声明它?我在某处看到全局变量很糟糕.

谢谢!

Ant*_*tti 6

你在想动态范围.动态范围的问题在于行为incrementc将取决于先前的函数调用,这使得很难推断代码.相反,大多数编程语言(也使用Python)都使用静态作用域:c仅在其中可见main.

要完成你想要的,你要么使用全局变量,要么更好地传递c作为参数.现在,因为Python中的原语是不可变的,所以传递一个整数是不能改变的(它实际上是通过值传递的),所以你必须将它打包到一个容器中,就像列表一样.像这样:

def increment(l):
    l[0] = l[0] + 1

def main():
    c = [5]
    increment(c)
    print c[0]

main()
Run Code Online (Sandbox Code Playgroud)

或者,甚至更简单:

def increment(l):
    return l + 1

def main():
    c = 5
    print increment(c)

main()
Run Code Online (Sandbox Code Playgroud)

通常,全局变量很糟糕,因为它们使得编写难以理解的代码变得非常容易.如果你只有这两个函数,你可以继续进行c全局化,因为代码的作用仍然很明显.如果你有更多的代码,最好将变量作为参数传递; 通过这种方式,您可以更轻松地查看谁依赖于全局变量.