2010-03-01 106 views
7

我目前正在用Python开发一些东西,并且我有一个关于变量范围的问题。关于变量范围的正确性

这是代码:

a = None 
anything = False 
if anything: 
    a = 1 
else: 
    a = 2 

print a # prints 2 

如果删除了第一线(=无)的代码仍然有效如前。但是在这种情况下,我会在“if”块中声明变量,并且关于其他语言(如Java),该变量只会在“if”中可见。

Python中确切的变量范围工作原理以及在这种情况下编程的好方法是什么?

谢谢!

+2

在python中没有“声明”一个变量的东西! – 2010-03-01 23:06:28

回答

8

作为一个经验法则,范围在三个地方被创建:

  1. 文件范围 - 另外称为模块范围
  2. 类范围 - 内class
  3. 函数作用域的创建 - 里面def

创建(有一些例外这些。)

分配给名称将其保留在范围名称空间中,标记为未绑定,直至到达第一个分配。因此,对于心理模型,您正在为范围中的名称分配值。

+1

实际上有四个地方,第四个是全球范围。但这真的取决于你是否认为全球范围本身就是一个范围。 – jathanism 2010-03-01 23:23:55

+1

据我了解全球范围,它通常是文件/模块范围的同义词。我所了解的例外涉及将全局变量字典传递给'exec'或'eval'。从内存中,第四个范围在生成器表达式中找到,不允许迭代器变量转义。第五个是关闭的非本地块范围 - 我从来没有找到一个简单的方法来解释这个范围。 – 2010-03-01 23:50:57

+0

+1好的答案。 – 2010-03-02 07:17:15

2

我相信Python使用函数作用域作为局部变量。也就是说,在任何给定的函数中,如果您为某个局部变量赋值,则该函数将从该函数内的那一刻起可用,直到它返回。因此,由于您的代码的两个分支都保证分配给a,所以最初不需要将None分配给a

请注意,如果您还可以访问在外部函数中声明的变量 - 换句话说,Python有闭包。

def adder(first): 
    def add(second): 
     return first + second 

    return add 

这定义了一个称为加法器的函数。当用参数first调用时,它将返回一个函数,它将接收的任何参数添加到first并返回该值。例如:

add_two = adder(2) 
add_three = adder(3) 
add_two(4) # = 6 
add_three(4) # = 7 

不过,虽然你可以阅读从外部函数的值,你不能改变它(不像许多其他语言)。例如,设想尝试实施累加器。你可能会写代码,像这样:

def accumulator(): 
    total = 0 
    def add(number): 
     total += number 
     return total 
    return add 

不幸的是,试图在一个错误信息使用此代码的结果:

UnboundLocalError: local variable 'total' referenced before assignment 

这是因为total += number试图线路改变total的价值,不能用在Python中以这种方式完成。

+0

您可以使用'nonlocal'(Python 3中的new)在'accumulator()'示例中执行所需的操作。 – 2010-03-01 23:33:52

0

Python不需要首先声明变量,所以你可以在任意点声明和定义。是的,范围是功能范围,所以它在if之外将是可见的。

1

if块中分配变量没有问题。

在这种情况下,它被分配到两个分支上,所以你可以看到它在你打印时肯定会被定义。

如果其中一个分支的没有分配给a那么当您尝试分支

0

我很初学者程序员后打印它NameError异常将会被提高,但我知道,在python私有变量不存在。有关详细讨论,请参阅python文档中的private variables

有用的信息也可以在同一页面上的“范围和名称空间”部分找到。

个人而言,我写这样你几乎每天张贴的一个,尤其是当条件

if len(sys.argv)==2: 
    f = open(sys.argv[1], 'r') 
else: 
    print ('provide input file') 

我做声明变量使用他们的结构化类型之前依靠从用户获得的输入,例如代码,例如我在一个循环中追加它的项目之前声明一个空列表。

希望它有帮助。