How do you assign to a variable in the root scope of a python program? [duplicate]

ساخت وبلاگ

Vote count: 219

What exactly are the Python scoping rules?

If I have some code:

code1
class Foo: code2 def spam..... code3 for code4..: code5 x()

Where is x found? Some possible choices include the list above:

  1. In the enclosing source file
  2. In the class namespace
  3. In the function definition
  4. In the for loop index variable
  5. Inside the for loop

Also there is the context during execution, when the function spam is passed somewhere else. And maybe lambda functions pass a bit differently?

There must be a simple reference or algorithm somewhere. It's a confusing world for intermediate Python programmers.

asked Nov 15 '08 at 1:48

7 Answers

Vote count: 204 accepted

Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply)

LEGB Rule.

L, Local — Names assigned in any way within a function (def or lambda)), and not declared global in that function.

E, Enclosing function locals — Name in the local scope of any and all enclosing functions (def or lambda), from inner to outer.

G, Global (module) — Names assigned at the top-level of a module file, or declared global in a def within the file.

B, Built-in (Python) — Names preassigned in the built-in names module : open,range,SyntaxError,...

So, in the case of

code1
class Foo: code2 def spam..... code3 for code4..: code5 x()

The for loop does not have its own namespace. In LEGB order, the scopes would be

L : local, in the current def.

E : Enclosed function, any enclosing functions (if def spam was in another def)

G : Global. Were there any declared globally in the module?

B : Any builtin x() in Python.

answered Nov 15 '08 at 12:47

Vote count: 94

Essentially, the only thing in Python that introduces a new scope is a function definition. Classes are a bit of a special case in that anything defined directly in the body is placed in the class's namespace, but they are not directly accessible from within the methods (or nested classes) they contain.

In your example there are only 3 scopes where x will be searched in:

  • spam's scope - containing everything defined in code3 and code5 (as well as code4, your loop variable)

  • The global scope - containing everything defined in code1, as well as Foo (and whatever changes after it)

  • The builtins namespace. A bit of a special case - this contains the various Python builtin functions and types such as len() and str(). Generally this shouldn't be modified by any user code, so expect it to contain the standard functions and nothing else.

More scopes only appear when you introduce a nested function (or lambda) into the picture. These will behave pretty much as you'd expect however. The nested function can access everything in the local scope, as well as anything in the enclosing function's scope. eg.

def foo(): x=4 def bar(): print x # Accesses x from foo's scope bar() # Prints 4 x=5 bar() # Prints 5

Restrictions:

Variables in scopes other than the local function's variables can be accessed, but can't be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope. For example:

global_var1 = []
global_var2 = 1
def func(): # This is OK: It's just accessing, not rebinding global_var1.append(4) # This won't affect global_var2. Instead it creates a new variable global_var2 = 2 local1 = 4 def embedded_func(): # Again, this doen't affect func's local1 variable. It creates a # new local variable also called local1 instead. local1 = 5 print local1 embedded_func() # Prints 5 print local1 # Prints 4

In order to actually modify the bindings of global variables from within a function scope, you need to specify that the variable is global with the global keyword. Eg:

global_var = 4
def change_global(): global global_var global_var = global_var + 1

Currently there is no way to do the same for variables in enclosing function scopes, but Python 3 introduces a new keyword, "nonlocal" which will act in a similar way to global, but for nested function scopes.

answered Nov 15 '08 at 21:51

Vote count: 42

There was no thorough answer concerning Python3 time, so I made an answer here.

As provided in other answers, there are 4 basic scopes, the LEGB, for Local, Enclosing, Global and Builtin. In addition to those, there is a special scope, the class body, which does not comprise an enclosing scope for methods defined within the class; any assignments within the class body make the variable from there on be bound in the class body.

Especially, no block statement, besides def and class, create a variable scope. In Python 2 the list comprehension does not create a variable scope, however in Python 3 the loop variable is created in a new scope.

To demonstrate the peculiarities of the class body

x = 0
class X(object): y = x x = x + 1 # x is now a variable z = x def method(self): print(self.x) # -> 1 print(x) # -> 0, the global x print(y) # -> NameError: global name 'y' is not defined
inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)

Thus unlike in function body, you can reassign the variable to the same name in class body, to get a class variable with the same name; further lookups on this name resolve to the class variable instead.


One of the greater surprises to many newcomers to Python is that a for loop does not create a variable scope. In Python 2 the list comprehensions do not create a scope either (while generators and dict comprehensions do!) Instead they leak the value in the function or the global scope:

>>> [ i for i in range(5) ]
>>> i
4

The comprehensions can be used as a cunning (or awful if you will) way to make modifiable variables within lambda expressions in Python 2 - a lambda expression does create a variable scope, like the def statement would, but within lambda no statements are allowed. Assignment being a statement in Python means that no variable assignments in lambda are allowed, but a list comprehension is an expression...

This behaviour has been fixed in Python 3 - no comprehension expressions or generators leak variables.


The global really means the module scope; the main python module is the __main__; all imported modules are accessible through the sys.modules variable; to get access to __main__ one can use sys.modules['__main__'], or import __main__; it is perfectly acceptable to access and assign attributes there; they will show up as variables in the global scope of the main module.


If a name is ever assigned to in the current scope (except in the class scope), it will be considered belonging to that scope, otherwise it will be considered to belonging to any enclosing scope that assigns to the variable (it might not be assigned yet, or not at all), or finally the global scope. If the variable is considered local, but it is not set yet, or has been deleted, reading the variable value will result in UnboundLocalError, which is a subclass of NameError.

x = 5
def foobar() print(x) # UnboundLocalError! x += 1 # assignment here makes x a local variable!

The scope can declare that it explicitly wants to modify the global (module scope) variable, with the global keyword:

x = 5
def foobar(): global x print(x) # -> 5 x += 1
foobar()
print(x) # -> 6

This also is possible even if it was shadowed in enclosing scope:

x = 5
y = 13
def make_closure(): x = 42 y = 911 def func(): global x # sees the global value print(x, y) x += 1 return func
func = make_closure()
func() # -> print 5 911
print(x, y) # -> 6 13

In python 2 there is no easy way to modify the value in the enclosing scope; usually this is simulated by having a mutable value, such as a list with length of 1:

def make_closure(): value = [0] def get_next_value(): value[0] += 1 return value[0] return get_next_value
get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2

However in python 3, the nonlocal comes to rescue:

def make_closure(): value = 0 def get_next_value(): nonlocal value value += 1 return value return get_next_value
get_next = make_closure() # identical behavior to the previous example.

Any variable that is not deemed to be local to the current scope, or any enclosing scope, is a global variable. A global name is looked up in the module global dictionary; if not found, the global is then looked up from the builtins module; the name of the module was changed from python 2 to python 3; in python 2 it was __builtin__ and in python 3 it is now called builtins. If you assign to an attribute of builtins module, it will be visible thereafter to any module as a readable global variable, unless that module shadows them with its own global variable with the same name.


Reading the builtin module can also be useful; suppose that you want the python 3 style print function in some parts of file, but other parts of file still use the print statement, if your python version is >= 2.6, you can get the new style function as:

import __builtin__
print3 = __builtin__.__dict__['print']

The from __future__ import print_function actually does not import the print function anywhere in Python 2 - instead it just disables the parsing rules for print statement in the current module, handling print like any other variable identifier, and thus allowing the print the function be looked up in the builtins.

answered May 5 '14 at 11:08

Vote count: 16

The scoping rules for Python 2.x have been outlined already in other answers. The only thing I would add is that in Python 3.0, there is also the concept of a non-local scope (indicated by the 'nonlocal' keyword). This allows you to access outer scopes directly, and opens up the ability to do some neat tricks, including lexical closures (without ugly hacks involving mutable objects).

EDIT: Here's the PEP with more information on this.

answered Nov 15 '08 at 18:52

Vote count: 9

A slightly more complete example of scope:

x = 100
print "1. Global x:", x
class Test(object): y = x print "2. Enclosed y:", y x = x + 1 print "3. Enclosed x:", x z = x def method(self): print "4. Enclosed self.x", self.x print "5. Global x", x try: print y except NameError, e: print "6.", e def method_local_ref(self): try: print x except UnboundLocalError, e: print "7.", e x = 200 print "8. Local x", x
inst = Test()
inst.method()
inst.method_local_ref()

output:

  1. Global x: 100
  2. Enclosed y: 100
  3. Enclosed x: 101
  4. Enclosed self.x 101
  5. Global x 100
  6. global name 'y' is not defined
  7. local variable 'x' referenced before assignment
  8. Local x 200
answered Dec 4 '15 at 17:38

Vote count: 6

Python resolves your variables with -- generally -- three namespaces available.

At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: the innermost scope, which is searched first, contains the local names; the namespaces of any enclosing functions, which are searched starting with the nearest enclosing scope; the middle scope, searched next, contains the current module's global names; and the outermost scope (searched last) is the namespace containing built-in names.

There are two functions: globals and locals which show you the contents two of these namespaces.

Namespaces are created by packages, modules, classes, object construction and functions. There aren't any other flavors of namespaces.

In this case, the call to a function named x has to be resolved in the local name space or the global namespace.

Local in this case, is the body of the method function Foo.spam.

Global is -- well -- global.

The rule is to search the nested local spaces created by method functions (and nested function definitions), then search global. That's it.

There are no other scopes. The for statement (and other compound statements like if and try) don't create new nested scopes. Only definitions (packages, modules, functions, classes and object instances.)

Inside a class definition, the names are part of the class namespace. code2, for instance, must be qualified by the class name. Generally Foo.code2. However, self.code2 will also work because Python objects look at the containing class as a fall-back.

An object (an instance of a class) has instance variables. These names are in the object's namespace. They must be qualified by the object. (variable.instance.)

From within a class method, you have locals and globals. You say self.variable to pick the instance as the namespace. You'll note that self is an argument to every class member function, making it part of the local namespace.

See Python Scope Rules, Python Scope, Variable Scope.

answered Nov 15 '08 at 2:03

Vote count: 5

Where is x found?

x is not found as you haven't defined it. :-) It could be found in code1 (global) or code3 (local) if you put it there.

code2 (class members) aren't visible to code inside methods of the same class — you would usually access them using self. code4/code5 (loops) live in the same scope as code3, so if you wrote to x in there you would be changing the x instance defined in code3, not making a new x.

Python is statically scoped, so if you pass ‘spam’ to another function spam will still have access to globals in the module it came from (defined in code1), and any other containing scopes (see below). code2 members would again be accessed through self.

lambda is no different to def. If you have a lambda used inside a function, it's the same as defining a nested function. In Python 2.2 onwards, nested scopes are available. In this case you can bind x at any level of function nesting and Python will pick up the innermost instance:

x= 0
def fun1(): x= 1 def fun2(): x= 2 def fun3(): return x return fun3() return fun2()
print fun1(), x
2 0

fun3 sees the instance x from the nearest containing scope, which is the function scope associated with fun2. But the other x instances, defined in fun1 and globally, are not affected.

Before nested_scopes — in Python pre-2.1, and in 2.1 unless you specifically ask for the feature using a from-future-import — fun1 and fun2's scopes are not visible to fun3, so S.Lott's answer holds and you would get the global x:

0 0
answered Nov 15 '08 at 12:44

back soft...
ما را در سایت back soft دنبال می کنید

برچسب : how do you say,how do you,how do you play pokemon go,how do you get bed bugs,how do you pronounce,how do you get coins in pokemon go,how do you get pink eye,how do you get hpv,how do you get scabies,how do you become a delegate, نویسنده : استخدام کار backsoft بازدید : 299 تاريخ : شنبه 27 شهريور 1395 ساعت: 17:03