python中的局部/全局变量混淆

python中的局部/全局变量混淆,python,Python,可能重复: 我在python中遇到了一个奇怪的错误。以下ipython日志对其进行了总结: In [10]: def confused(stuff): ....: print huh ....: return stuff ....: In [11]: confused(87) 0 Out[11]: 87 In [12]: def confused(stuff): ....: print huh ....: huh += 1

可能重复:

我在python中遇到了一个奇怪的错误。以下ipython日志对其进行了总结:

In [10]: def confused(stuff):
   ....:     print huh
   ....:     return stuff
   ....: 

In [11]: confused(87)
0
Out[11]: 87

In [12]: def confused(stuff):
   ....:     print huh
   ....:     huh += 1
   ....:     return stuff
   ....: 

In [13]: confused(9)
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
/home/max/verk/btr-email/build/x86_64/bin/ipython in <module>()
----> 1 confused(9)

/home/max/verk/btr-email/build/x86_64/bin/ipython in confused(stuff)
      1 def confused(stuff):
----> 2     print huh
      3     huh += 1
      4     return stuff

UnboundLocalError: local variable 'huh' referenced before assignment
[10]中的
:定义混乱(内容):
……打印,嗯
归还物品
....: 
在[11]中:混淆(87)
0
Out[11]:87
在[12]中:定义(内容):
……打印,嗯
..:huh+=1
归还物品
....: 
在[13]中:混淆(9)
---------------------------------------------------------------------------
取消绑定LocalError回溯(最近一次调用上次)
/home/max/verk/btr email/build/x86_64/bin/ipython in()
---->1(9)
/home/max/verk/btr-email/build/x86_64/bin/ipython-in-fuzzle(东西)
1.2.2(材料):
---->2张照片,嗯
3+1
4退货
UnboundLocalError:赋值前引用了局部变量“huh”
工作的函数和抛出错误的函数之间的唯一区别是+=1行,即使如此,它也会在先前工作的行上抛出错误!如果我在方法的第二个版本中引用
huh
之前放置
global huh
,它也不会抛出错误


为什么在向变量添加一行的地方添加一行会突然将其从全局变量更改为局部变量?

在脚本中,
huh
指的是一个全局变量。在函数中更改对全局变量的引用时,必须明确告诉python这是您想要做的:

def confused(stuff):
    global huh
    print huh
    huh += 1
    return stuff
对于不可变的对象,如int、string、float等,这意味着如果不将对象声明为
global
,则无法对其进行任何更改。对于可变对象,可以对对象项或属性进行更改,但仍然不能更改对象的引用


这都是一个范围问题。由于
huh
不在
fuzzle
的本地范围内,因此python会在全局范围内找到它。因为它是在全局范围内找到的,所以除非您明确表示希望(使用
global
,正如我在上面所做的那样),否则不能分配给它。但是,如果它是一个
列表
,一旦找到该列表,您就可以访问该列表的所有方法(包括
\uuuuuuu setitem\uuuuuu
append
,等等)


至于错误的位置,可以通过一点
dis
组装来消除:

>>> def confused(stuff):
...    print huh
... 

>>> import dis
>>> dis.dis(confused)
  2           0 LOAD_GLOBAL              0 (huh)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE

>>> def confused2(stuff):
...    print huh
...    huh += 1
... 

>>> dis.dis(confused2)
  2           0 LOAD_FAST                1 (huh)
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       

  3           5 LOAD_FAST                1 (huh)
              8 LOAD_CONST               1 (1)
             11 INPLACE_ADD         
             12 STORE_FAST               1 (huh)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE   

您可以看到,在
confused2
中,python已经尝试在函数的第一行
LOAD\u FAST
(意思是查找局部变量)。但是,不存在局部变量
huh
,因此存在异常。

但是我经常在函数中更改全局字典或列表,而不将它们声明为全局…@mattedgod--如果您从中了解到,再学习一件事——很少建议使用
global
语句。@mgilson很明显,我没有太多地使用它,所以我认为我在这方面做得很好:)@mavix——请参阅我的更新。希望我的措辞更清楚一些…@mavix除了mgilson所说的之外,这个确定什么是局部变量和什么是全局变量的规则消除了声明局部变量的需要(到目前为止,这是最常见的一种,所以我们不希望它过于冗长),同时允许访问只读全局变量(包括类、函数、导入等,因为它们都共享相同的名称空间)并且仅从函数的代码中就可以清楚地区分全局变量和局部变量。