Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
395 views
in Technique[技术] by (71.8m points)

python - Unbound variable and name

According to the python reference manual we have

When a name is not found at all, a NameError exception is raised. If the name refers to a local variable that has not been bound, a UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.

I don't to understand when the UnboundLocalError is thrown? Because

Python lacks declarations and allows name binding operations to occur anywhere within a code block.

So how we can declare a variable, but not to initialize her?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can refer to a name without having assigned to it:

>>> foobar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foobar' is not defined

Here foobar is being referred to, but was never assigned to. This raises a NameError because the name was never bound.

More subtly, here assignment is not happening because the line that does is never run:

>>> def foo():
...     if False:
...         spam = 'eggs'
...     print spam
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in foo
UnboundLocalError: local variable 'spam' referenced before assignment

Because spam = 'eggs' is never executed, print spam raises an UnboudLocalError.

Note that nowhere in Python is a name ever declared. You bind or don't bind, declaration is not part of the language.

Instead, binding is used to determine the scope of a name; binding operations include assignment, names used for a for loop, function parameters, import statements, name to hold a caught exception in an except clause, the name for a context manager in a with statement all bind names.

If a name is bound in a scope (such as in a function) then it is a local name, unless you use a global statement (or a nonlocal statement in Python 3) to explicitly mark the name as a global (or a closure) instead.

So the following is an error:

>>> foo = None
>>> def bar():
...     if False:
...         foo = 'spam'
...     print foo
... 
>>> bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bar
UnboundLocalError: local variable 'foo' referenced before assignment

because foo is being bound somewhere in the bar function scope. But if you mark foo as a global, the function works:

>>> foo = None
>>> def bar():
...     global foo
...     if False:
...         foo = 'spam'
...     print foo
... 
>>> bar()
None

because now the Python compiler knows you wanted foo to be a global instead.

This is all documented in the Naming and Binding section of the Python reference documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...