How does Python scope work?

This wants me to dig deeper into Python sources, but since there are many people on SO who have already done this, I would love to hear their pointers.

>>> import os >>> def scope(): ... print os ... import os ... >>> scope() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in scope UnboundLocalError: local variable 'os' referenced before assignment 

It seems to me that when the parser interprets the file, it automatically creates a local scope for the scope function, which makes os "disconnected" from the global scope.

It's true? Anyone want to tell me where I can find more about the implementation of the area?

EDIT: Also, this is not a special import case, it also works for regular variables.

+4
source share
3 answers

When you call scope() Python sees that you have a local variable called os used inside your method (from import inside scope ), so this masks the global os . However, when you say print os , you did not reach the line and did local import, but you see an error regarding the link before the destination. Here are some other examples that might help:

 >>> x = 3 >>> def printx(): ... print x # will print the global x ... >>> def printx2(): ... print x # will try to print the local x ... x = 4 ... >>> printx() 3 >>> printx2() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in printx2 UnboundLocalError: local variable 'x' referenced before assignment 

And back to your os example. Any os assignment has the same effect:

 >>> os <module 'os' from 'C:\CDL_INSTALL\install\Python26\lib\os.pyc'> >>> def bad_os(): ... print os ... os = "assigning a string to local os" ... >>> bad_os() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in bad_os UnboundLocalError: local variable 'os' referenced before assignment 

Finally, compare these 2 examples:

 >>> def example1(): ... print never_used # will be interpreted as a global ... >>> def example2(): ... print used_later # will be interpreted as the local assigned later ... used_later = 42 ... >>> example1() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in example1 NameError: global name 'never_used' is not defined >>> example2() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in example2 UnboundLocalError: local variable 'used_later' referenced before assignment 
+5
source

Lexical scope is a common thing, and most well-designed languages, whether interpreted or compiled, use it.

I have not tried this for a while, but pay attention to the excellent "global" keyword and its use below:

 o = 1 def foo(): global o o = 2 foo() print o 

Without the "global" line, the change in o is localized, and printing "print o" 1. When the line "global o" is on, it prints 2. We call it so that my function (without global o) above will have its own variables. The global thing above is a way to specifically request an exception for normal lexical coverage.

True lexical reach is what Python 1.0 lacked and which Python has had for a long time (since at least 1.6, if I remember correctly). There were only two areas, local and global, and any intermediate areas were inaccessible.

+1
source

Any binding of a variable inside a function makes the variable local to this function. import , def and class equivalent to assignment in this regard.

So yes, when the compiler compiles your file, it creates a local os variable, which is divided into areas from the global os .

See the Python manual for more information. In particular, http://docs.python.org/tutorial/classes.html section 9.2

0
source

Source: https://habr.com/ru/post/1314055/


All Articles