2017-02-23 144 views
0

我曾经用C,C#和Java编程。现在我正在使用Python一段时间,但是我在理解变量作用域时遇到了一些问题,这对我来说现在非常困惑。例如:混淆变量作用域(来自外部作用域的阴影变量)

def f1(): 
    print(spam) # spam magically come from outer scope. ok... 


def f2(): 
    spam = "bbb" # assignment shadows variable from outer scope (logical result of f1) 
    print(spam) # printing local spam variable 


def f3(): 
    print(spam) # ERROR: unresolved reference 'spam' 
    spam = "ccc" # in f1 function everything was fine but adding assignment AFTER 
        # printing (in opposite to f2 function) causes error in line above 


def f4(): 
    print(spam) # nothing wrong here, assignment line below is commented 
    # spam = "ccc" 

spam = "aaa" 

为什么地球上的功能可能会超出其范围之外的变量? 为什么从外部范围的阴影变量是好的,但只有我们以前没有使用它?

+1

你肯定你会在'f3'中得到'未解决的参考错误'?我期望在赋值之前引用错误'UnboundLocalError:本地变量'垃圾邮件',这是相当自我解释的。 – kazemakase

+0

'f2'发生了什么变化'垃圾'从'aaa'到'bbb' – mtkilic

+0

@kazemakase你说得对,我写的错误是从IDE而不是运行时 – user3616181

回答

1

Python代码在执行前被编译为字节码。这意味着Python可以分析函数如何使用变量。一个变量是全球本地在一个函数,但不是两个,它不能改变。

spamf1是全球性的,因为它从未被分配。 spam在本地f2因为它被分配。 f3也是如此。 spam由于spam='ccc'而在f3中位于本地。用print(spam)语句尝试访问本地变量,然后分配它。

您可以在函数内部使用global spam来强制声明变量名称为全局变量名称。

当地人住在当地。即使在本地命名空间中删除一个变量之后,Python不查找名称父范围:

spam = 123 

def f(): 
    spam = 42 
    print(spam) # 42 
    del spam 
    print(spam) # UnboundLocalError 

f() 

如果你想分配给你需要声明一个全局的变量:

spam = 123 

def f(): 
    global spam 
    spam = 42 
    print(spam) # 42 

f() 
print(spam) # 42 
+0

哦,我忘记了,甚至很多人都说python是从其实际编译阶段的脚本中解释出来的。 – user3616181

+0

但为什么函数可以达到外部变量?这背后有什么想法?因为有人必须得出结论,这是一个理想的行为 – user3616181

+0

@ user3616181因为在Python中变量,函数和其他对象之间没有区别。你希望能够在你的函数定义中调用'print',不是吗? 'print'是一个全局对象,'spam'也是。 '垃圾邮件'也可以是你想在你的其他功能中调用的函数。没有理由不允许全局查找。我曾经想过关闭这个功能,但这竟然是[坏主意](http://stackoverflow.com/a/31023487/3005167)。 – kazemakase