相关疑难解决方法(0)

Python变量范围错误

以下代码在Python 2.5和3.0中按预期工作:

a, b, c = (1, 2, 3)

print(a, b, c)

def test():
    print(a)
    print(b)
    print(c)    # (A)
    #c+=1       # (B)
test()
Run Code Online (Sandbox Code Playgroud)

但是,当我取消注释行(B)时,我得到了UnboundLocalError: 'c' not assigned一行(A).的值ab被正确地打印.这让我感到困惑,原因有两个:

  1. 为什么在行(A)处抛出运行时错误,因为后面的行(B)语句?

  2. 为什么变量ab打印符合预期,同时c引发错误?

我能想到的唯一解释是,赋值创建了一个局部变量,即使在创建局部变量之前,它也优先于"全局"变量.当然,变量在存在之前"窃取"范围是没有意义的.cc+=1c

有人可以解释一下这种行为吗?

python variables scope

195
推荐指数
7
解决办法
6万
查看次数

不直观的UnboundLocalError行为的原因

注意:有一个非常类似的问题在这里.但是,请耐心等待; 我的问题不是"为什么会发生错误",而是"为什么Python实现为在这种情况下抛出错误."

我只是偶然发现了这个:

a = 5
def x()
    print a
    a = 6
x()
Run Code Online (Sandbox Code Playgroud)

抛出一个UnboundLocalException.现在,我确实知道为什么会发生这种情况(后来在这个范围内,a受到限制,因此a在整个范围内都被认为是本地的).

在这种情况下:

a = 5
def x()
    print b
    b = 6
x()
Run Code Online (Sandbox Code Playgroud)

这非常有意义.但第一种情况有一个直观的逻辑,这意味着:

a = 5
def x()
    print globals()["a"]
    a = 6 # local assignment
x()
Run Code Online (Sandbox Code Playgroud)

我想有一个原因是为什么不允许"直觉"版本,但它是什么?虽然这可能是"明确比隐含更好"的情况,但摆弄着globals()总觉得我有点不洁净.

从这个角度来看,发生在我身上的实际情况是别人的剧本,我不得不改变一下.在我的(短暂的)更改中,我在脚本运行时进行了一些文件重命名,所以我插入了

import os
os.rename("foo", "bar")
Run Code Online (Sandbox Code Playgroud)

进入脚本.这个插入发生在一个函数内部.模块已经os在顶级导入(我没有检查过),有些os.somefunction调用在函数内部进行,但在插入之前.这些电话显然触发了一个UnboundLocalException.

那么,有人可以向我解释这个实现背后的原因吗?是为了防止用户犯错误?"直观"的方式会让字节码编译器的内容变得更复杂吗?或者是否有一种我没有想到的歧义?

python

5
推荐指数
1
解决办法
555
查看次数

Python模块(在赋值之前引用的模块名称)

vm.pymain()脚本(getdata.py)在一个目录中.在getdata.py,我有

import vm
...
x = vm.Something()
Run Code Online (Sandbox Code Playgroud)

然后python抱怨

UnboundLocalError: local variable 'vm' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

这是为什么?导入时没有错误.

UPDATE

我发现如果我这样做了

from vm import * 
Run Code Online (Sandbox Code Playgroud)

相反,它奏效了.另外对于我制作的另一个文件/模块,一个简单的import工作.我将完整代码上传到GitHub Gist https://gist.github.com/2259298

python python-3.x

3
推荐指数
1
解决办法
1776
查看次数

标签 统计

python ×3

python-3.x ×1

scope ×1

variables ×1