在 Python 中赋值之前引用的局部变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18002794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:41:45  来源:igfitidea点击:

Local variable referenced before assignment in Python?

pythonpython-2.7python-3.xvariable-assignment

提问by Scooby

I am using the PyQt library to take a screenshot of a webpage, then reading through a CSV file of different URLs. I am keeping a variable feed that incremements everytime a URL is processed and therefore should increment to the number of URLs.

我正在使用 PyQt 库截取网页的屏幕截图,然后阅读不同 URL 的 CSV 文件。我保留了一个可变提要,每次处理 URL 时都会增加它,因此应该增加到 URL 的数量。

Here's code:

这是代码:

webpage = QWebPage()
fo = open("C:/Users/Romi/Desktop/result1.txt", "w")
feed = 0
def onLoadFinished(result):
    #fo.write( column1[feed])#, column2[feed], urls[feed])
   #feed = 0
   if not result:
        print "Request failed"
    fo.write(column1[feed])
    fo.write(',')
    fo.write(column2[feed])
    fo.write(',')
    #fo.write(urls[feed])
    fo.write(',')
    fo.write('404,image not created\n')
    feed = feed + 1
        sys.exit(1)
        save_page(webpage, outputs.pop(0))   # pop output name from list and save
   if urls:
        url = urls.pop(0)   # pop next url to fetch from list
        webpage.mainFrame().load(QUrl(url))
    fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n')
    fo.write(',')
    fo.write(column2[feed])
    fo.write(',')
    #fo.write(urls[feed])
    fo.write(',')
    fo.write('200,image created\n')
    feed = feed + 1
   else:
        app.quit()  # exit after last url

webpage.connect(webpage, SIGNAL("loadFinished(bool)"), onLoadFinished)
webpage.mainFrame().load(QUrl(urls.pop(0)))
#fo.close()
sys.exit(app.exec_())

It gives me the error:

它给了我错误:

local variable feed referenced before the assignment at fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n')

Any idea why?

知道为什么吗?

采纳答案by unutbu

When Python parses the body of a function definition and encounters an assignment such as

当 Python 解析函数定义的主体并遇到赋值时,例如

feed = ...

Python interprets feedas a local variable by default. If you do not wish for it to be a local variable, you must put

Pythonfeed默认解释为局部变量。如果你不希望它是一个局部变量,你必须把

global feed

in the function definition. The global statement does not have to be at the beginning of the function definition, but that is where it is usually placed. Wherever it is placed, the global declaration makes feeda global variable everywherein the function.

在函数定义中。global 语句不必位于函数定义的开头,而是通常放置的位置。无论放在何处,全局声明都会在函数中的任何地方生成feed一个全局变量。

Without the global statement, since feedis taken to be a local variable, when Python executes

没有global语句,因为feed被认为是局部变量,当Python执行时

feed = feed + 1,

Python evaluates the right-hand side first and tries to look up the value of feed. The first time through it finds feedis undefined. Hence the error.

Python 首先评估右侧并尝试查找 feed 的值。第一次通过它发现feed是未定义的。因此错误。

The shortest way to patch up the code is to add global feedto the beginning of onLoadFinished. The nicer way is to use a class:

修补代码的最短方法是添加global feedonLoadFinished. 更好的方法是使用一个类:

class Page(object):
    def __init__(self):
        self.feed = 0
    def onLoadFinished(self, result):
        ...
        self.feed += 1

The problem with having functions which mutate global variables is that it makes it harder to grok your code. Functions are no longer isolated units. Their interaction extends to everything that affects or is affected by the global variable. Thus it makes larger programs harder to understand.

具有改变全局变量的函数的问题在于它使您的代码更难理解。函数不再是孤立的单元。它们的交互扩展到影响全局变量或受全局变量影响的所有事物。因此,它使更大的程序更难理解。

By avoiding mutating globals, in the long run your code will be easier to understand, test and maintain.

通过避免改变全局变量,从长远来看,您的代码将更易于理解、测试和维护。

回答by Scooby

Put a global statement at the top of your function and you should be good:

在函数的顶部放置一个全局语句,你应该很好:

def onLoadFinished(result):
    global feed
    ...

To demonstrate what I mean, look at this little test:

为了证明我的意思,请看这个小测试:

x = 0
def t():
    x += 1
t()

this blows up with your exact same error where as:

这会因您的完全相同的错误而爆炸,其中:

x = 0
def t():
    global x
    x += 1
t()

does not.

才不是。

The reason for this is that, inside t, Python thinks that xis a local variable. Furthermore, unless you explicitly tell it that xis global, it will try to use a local variable named xin x += 1. But, since there is no xdefined in the local scope of t, it throws an error.

这样做的原因是,在里面t,Python 认为这x是一个局部变量。此外,除非您明确告诉它x是全局变量,否则它将尝试使用名为xin的局部变量x += 1。但是,由于x在 的本地范围内没有定义t,因此会引发错误。

回答by lmjohns3

As the Python interpreter reads the definition of a function (or, I think, even a block of indented code), all variables that are assigned toinside the function are added to the locals for that function. If a local does not have a definition before an assignment, the Python interpreter does not know what to do, so it throws this error.

当 Python 解释器读取函数的定义(或者,我认为,甚至是缩进代码块)时,分配给函数内部的所有变量都会添加到该函数的局部变量中。如果局部变量在赋值之前没有定义,Python 解释器不知道该怎么做,所以它会抛出这个错误。

The solution here is to add

这里的解决方案是添加

global feed

to your function (usually near the top) to indicate to the interpreter that the feed variable is not local to this function.

到您的函数(通常靠近顶部)以向解释器表明 feed 变量不是该函数的本地变量。