Instant Search

Namespaces, Scope Resolution, and LEGB Rule

So , I am here and i wanted to explain what is Namespace , Scope and LEGB rule in python. What are local and global variable and what is the use of Namespace in programming language.

Let’s divide our work under Six sections:

Name,
Namespace,
Scope
Global and Local Variables,
LEGB rule
Import module

So what’s in name?

Simply a name means variable in python , When we define a variable we are giving it a name and that variable is assigning a object which is holding the value. Variable are dynamic type in python , means you can re-use the variable with different data types.

let’s say :

so here a is a variable its referring a object 1 , so “a” is just referring a object its not holding the value. lets say:

So now we assigned a=1 and then b=1 and so on but here as you can see name are changing but object id are same. if you have remember i have explained the concept of object in previous post in terms of body , soul , and name. So as a person can have a name , a body and a soul . Person’s name is “variable” , Person body is object which holding the soul and person’s soul is value. So a person can have many names like tim , exe , paul etc but all name denoting same body. it means a variable can have many names but they will denote same object if we change the object it means we are changing the body and now its denoting different object . No longer same person. but if we change the name as many as we want then it will never affect body and soul (object and value) .

as in example a had value “1” when we assign value to b then b have now holding the object which have value “1” then when we assign same value to c then now c is holding the same value and id of all the variables are same because they are holding the same object and that object is holding the value. it means all the name are pointing one and only one object whose id is 4297148528 for better understanding see the image below :

heiiao

So it doesn’t matter how many names a person have but it will all denote to one body and if person dies then all the name associated with him will eventually destroyed.

Name (also called identifier) is simply a name given to objects. Everything in Python is an object. Name is a way to access the underlying object.

An object can have any number of names, or no name at all.

Names live in namespaces (such as a module namespace, an instance namespace, a function’s local namespace).

Namespaces are collections of (name, object reference) pairs (implemented using dictionaries).

When you call a function or a method, its namespace is initialized with the arguments you call it with (the names are taken from the function’s argument list, the objects are those you pass in).

A name in Python is roughly analogous to a variable in just about any other language, but with a few extras. First of, because of Python’s dynamic nature, you can apply a name to just about anything. You can of course give names to values.

But you can also give names to things like functions:

Now whenever you want to use func(), you can use f() instead. You can also take a name and reuse it. For example, the following code is perfectly legal in Python:

If you accessed the name var in between assignments, you’d get a number, a string and a list at different times. Names go hand in hand with Python’s object system, ie. everything in Python is an object. Numbers, strings, functions, classes are all object. The way to get to the objects is often through a name.

Enough about Name let’s talk about Namespace now:

Namespace:

first i will suggest this video about namespace which explain awesome :

what happens in Python when we use the assignment operator.  set the value to variable  and refer to the object which holding that value . A variable is just a name which refer to the object ,

In Python, you can imagine a namespace as a mapping of every name, you have defined, to corresponding objects.

A namespace containing all the built-in names is created when we start the Python interpreter and exists as long we don’t exit.

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

This is the reason that built-in functions like id(), print() etc. are always available to us from any part of the program. Each module creates its own global namespace.

These different namespaces are isolated. Hence, the same name that may exist in different modules do not collide.

Namespaces are collection of those variables and objects which we have defined. It simply map the variable to object , which variables and objects we have defined.

i suggest you go to watch this video:

let’s understand this by example :-

x=1  here x is name and 1 is object so now namespace will map name x to its objects 1.
names are store in one dict and objects are stored in another dict so namespace map “name” from one dict to “object” from another dict.

As you can see in video , names are stored in one dict and objects are stored in another dict.

Namespaces are collections of (name, object reference) pairs (implemented using dictionaries).

When you call a function or a method, its namespace is initialized with the arguments you call it with (the names are taken from the function’s argument list, the objects are those you pass in).

Just think of it that if you have defined three or more objects and you have to access those objects how you will access ? simply you will use objects name which is variable and use that variable in program but how object will know which name it have defined that’s where the “Namespace” comes in game.
Just think you all three or more objects stored in one dict and the variables name are stored in another dict now namespace will point object to its variable in which way we have defined variable.  Or namespace will point one dict of object to other dict of  their name.

Let say we defined a simple string here:

hello=”exe” , here hello is name variable which is referring the “exe” string type object now we can access “exe” object just by using name “hello”. we can access via its variable name.

We can picture a namespace as a Python dictionary structure, where the dictionary keys represent the names and the dictionary values the object itself (and this is also how namespaces are currently implemented in Python), e.g.,

Now, the tricky part is that we have multiple independent namespaces in Python, and names can be reused for different namespaces (only the objects are unique, for example:

For example, everytime we call a for-loop or define a function, it will create its own namespace. Namespaces also have different levels of hierarchy (the so-called “scope”).

Think about that “math” module also have __add__ and list module also __add__ so how they are different from each other , Its work of namespace.

like if we add 3+4 then it will return 7 but if we do [3]+[4] then it will return [7]

now if two module have same function then namespace will keep both function different.

Each namespace is also completely isolated. So two modules can have the same names within them. You can have a module called Integer and a module called FloatingPoint and both could have a function named add(). Once you import the module into your script, you can access the names by prefixing them with the module name: FloatingPoint.add() and Integer.add().

Whenever you run a simple Python script, the interpreter treats it as module called __main__, which gets its own namespace. The builtin functions that you would use also live in a module called __builtin__ and have their own namespace.

if the above definition comes from a module named hello.py, we might just call the function hello_worldunstead of main. But this solution leaves much to the discretion of individual programmers, and has significant limitations. As your knowledge of Python grows, you will find yourself loading more and more Python modules, many of them containing code (and therefore names) you have never looked at. This raises the likelihood of a nameclash, and therefore a mysterious and hard to detect bug, considerably. Since naming conventions and the ability to use them consistently vary considerably, Python has implemented a more general solution: When a module hello is loaded with the command,:

and the module defines a function main, the name main is not associated with the function definition. Instead the name hello.main is. The way to call “main” is to type:

If the programmer then types,:

the name main is set to denote the integer and the name hello.main in unaffected, so the commandmain.hello() will work as intended.

The technical name for the Pythonic solution is namespaces. That is, by default, each module has anamespace of its own, the names beginning with the module name followed by ”.”. Thus the name space of the “hello” module is all names beginning with “hello.”, the name space of a module named “goodbye” is “goodbye.”, and if both define functions named “main”, one will be accessible under the name “hello.main” and the other under the name “goodbye.main”.

Every name available in Python belongs to some namespace. The namespace containing all the names available when you start up Python is called __builtins__. Every name in __builtins__ belongs to the toplevel namespace and therefore does not have to be prefixed with a module name. The dircommand will list those names:

Ok now i think you got a very good idea about namespaces , conclusion we can say Variables are just name , they don’t hold any values they hold object reference now how computer or program will remember that which name associated with which object so for remembering this program use “Namespace” Namespace work is when we call any variable by its name then it simply point that variable to its object . All variables names store in big dict and all objects stored in another big dic which looks something like this :

namespace in python

In above namespace “Names” are big dict of all variables name and “Object” are big dict of all objects associated with their name.

In above namespace “x” is pointing an object which have value 3 so its int type object.
“Y” variable is pointing an object which have value 5 so its also int type object.
“exe” variable  is pointing an object which have value “Ankit” which is string type object.
“tim” variable  is pointing an object which have value 1337 which is int type of object.

#Naming and Binding :

when a variable refer to an object which holds any value this is called “Naming and Binding”

Now let’s talk about scope in python.

Scope in python:

Scope define rules for variables , Scope define where a variable is accessible and what is lifetime of that variable. The reign where a variable can be use that called scope for that variable. Or the portion of program in which that variable can be use that called scope of that variable.

Not all variables are accessible from all parts of our program, and not all variables exist for the same amount of time. Where a variable is accessible and how long it exists depend on how it is defined. We call the part of a program where a variable is accessible its scope, and the duration for which the variable exists its lifetime.

we may not be able to access all of them from every part of the program. The concept of scope comes into play.

Scope is the portion of the program from where a namespace can be accessed directly without any prefix.

At any given moment, there are at least three nested scopes.

  1. Scope of the current function which has local names
  2. Scope of the module which has global names
  3. Outermost scope which has built-in names

When a reference is made inside a function, the name is searched in the local namespace, then in the global namespace and finally in the built-in namespace.

The “scope” in Python defines the “hierarchy level” in which we search namespaces for certain “name-to-object” mappings.
For example, let us consider the following code:

 

Here, we just defined the variable name i twice, once on the foo function.

  • foo_namespace = {'i':object_3, ...}
  • global_namespace = {'i':object_1, 'name_b':object_2, ...}

So, how does Python know which namespace it has to search if we want to print the value of the variable i? This is where Python’s LEGB-rule comes into play.

Example:

Output is :

 

 

why x is printing 11 when we already defined x=111 in top of line of program?
Who define the lifetime of x =1 ? why last print and first print printing x=111 and middle print function printing x=1 ?
The lifetime and uses of “x” in this program defined by scope , scope define where is local variable is accessible and where is global variable is accessible.
local variable life is only inside that function but global variable life is in whole program.

In Python, you can always determine the scope of any name just by looking at the program. The scope of a name does not change while the program is running. (In formal terms, Python is a lexically scoped language.) If a binding for a variable appears anywhere inside a function, that variable name is local to the function.

So in simple words the portion of the program in which we can access that variable are called scope of variable. Scope define lifetime and uses of variables in program.

 

Now let’s talk about what is local and global variables:

 

Local and Global variable:

Local variable lifetime is only inside function but global variable lifetime is in whole function. Global variables are accessible inside and outside of functions. Local variables are only accessible inside the function.

python defines the following four scopes.

  1. The innermost scope, which is searched first, contains the local names
  2. The scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
  3. the next-to-last scope contains the current module’s global names
  4. the outermost scope (searched last) is the namespace containing built-in names.

Take a look of this program:

in this program first x which is defined at top of program is called Global variable and the “x” variable which is defined inside function is called local variable.

When a line of code asks for the value of a variable x, Python will search for that variable in all the available namespaces, in order:

  1. alocal namespace – specific to the current function or class method. If the function defines a local variable x, or has an argument x, Python will use this and stop searching.
  2. global namespace – specific to the current module. If the module has defined a variable, function, or class called x, Python will use that and stop searching.
  3. built-in namespace – global to all modules. As a last resort, Python will assume that x is the name of built-in function or variable.

If Python doesn’t find x in any of these namespaces, it gives up and raises a NameError with the message There is no variable named 'x'

locals is read-only, globals is not

ocals() Is Read-Only: globals() Is Not

locals() Is Read-Only: globals() Is Not


  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

 

we can define global function simply by putting variable value outside functions or top of program. Second method is we can define any variable as global by using “global” keyword.

Defining #global variable in program:

Defining global by putting variable at top of program

 

Second method by using global method:

we can check all local variables by using locals() function.

 

output:

As you can see we have defined x=1 , exe=”ankit” and paul=1337 as local variables in program , because these variables are defined inside function so its lifetime are only in inside function and its scope is inside function so when we use locals() it print all local variables defined in program.

We can check all global variables by using globals() function:

 


output:

 


As you can see it print out all the global variables which are present in program.  __doc__ and other variables are globally variables which we don’t have to define they present all time when we start python editor.

Now let’s talk about LEGB rule which is must to understand :

LEGB RULE:

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, len,range,SyntaxError,…

So, in the case of:

 

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.

where the arrows should denote the direction of the namespace-hierarchy search order.

  • Local can be inside a function or class method, for example.
  • Enclosed can be its enclosing function, e.g., if a function is wrapped inside another function.
  • Global refers to the uppermost level of the executing script itself, and
  • Built-in are special names that Python reserves for itself.

So, if a particular name:object mapping cannot be found in the local namespaces, the namespaces of the enclosed scope are being searched next. If the search in the enclosed scope is unsuccessful, too, Python moves on to the global namespace, and eventually, it will search the built-in namespace (side note: if a name cannot found in any of the namespaces, a NameError will is raised).

Namespaces can also be further nested, for example if we import modules, or if we are defining new classes. In those cases we have to use prefixes to access those nested namespaces. Let me illustrate this concept in the following code block:

This is also why we have to be careful if we import modules via “from a_module import *”, since it loads the variable names into the global namespace and could potentially overwrite already existing variable names

 

Let’s see an example:

Local and Global :

when we will run this program  we will get output 1,5 because program will start from first line and it will go in function line but function is not called yet so it will skip code inside of function and now it will go print statement which is defined outside of the functionwhen print is defined outside of function now it will search for variable i in local namespace but i is not defined in local because we are now outside of the function so now it will check global namespace for variable i and it will find i=1 so now it will print 1 now next line is calling function line  so now it will go to the function and this time it will execute the code inside of function  first  , the program will search in local namespace for the object for the variable  and it will found i=5 so it will print. That’s how it works.

output :

here why :

because we can modify global keyword by re-assign a new value to it.

first program will start from first line and it will skip function part because function have not called yet so it will not execute code inside of the function. next it will go to print statement which is defined outside of the function now it will search a_var value for local namespace but as we know program have skipped function because function is not called yet so there is no local defined variable now when it will not found in local it will search for global and now it will find a_var value in first line of program which is global defined and it will print. Remember one thing as i explained how we can create a global variable just by using “global” keyword so we have defined a variable as global by using “global” keyword inside function in local namespace but then why function search a_var in global namespace ? because program skipped the function part because it was not called that time so that’s why code inside function is useless until function didn’t called. it will not execute until function called.

Now when it will reach the line “a_func()” in program and this is calling function its calling the function now program will execute code inside in function and now global variable is a_var and first it will print “local value 5” which is defined after “global a_var)  because it found value in local namespace. next line is print line which is defined outside of the function so as function exist all the local variable destroyed inside of function but as we know we have defined a_var as global variable so it will not destroyed and now when outside print will look value for a_var it will not print global value from global namespace which is  ”

instead of it will print

because now global variable is modified and it is now a_var which is defined in function so now once function executed after that global keyword will be always use from function localspace of global keyword which is

Now let’s talk about enclosed scope:

Enclosed

Following the order “Local -> Enclosed -> Global”,

enclosed means which are defined in nested function and closed by function.

let’s take a look of this program:

output is :

can you see what is happening here?

Inside function first print will print global value of x which is “22” but when we will enter in nested function then global value is changed now , now global value for x is “jj” which is local namespace in first function. its called enclosed namespace. now nested print will print x=”jj” because it will always consider x=”jj” as global value for all the function nested in main function.

x=”jj” is gobal variable for nested function. this is enclosed scope .
nested value will not take x=”22″ as global value it will always take x=”jj” as global value because its enclose scope for nested function.

for more clarification of this point consider this program :

 

output of this program:

let me explain what happened there :

for each nested function global value change , it will not take global value for global namespace nested function always first take global value from enclosed scope and  it value not found there then they will find in global namespace.

that’s why for function “he” global value is x=”jj” but when we reassign  value of x with x=”qq”  now for function “he” local value of x is “qq” and global value is x=”jj”

for function “howdy” global value is not x=”jj”  it have been changed now . Now global value for function “howdy” is local value of previous function which is x=”qq”  because “howdy” is nested function for “he” function that’s why it will take value from enclosed scope when we  assign new value to x which is x=”hui” , now local value of x is “hui” for function “howdy and global value is x=”qq” for function “howdy”.

after this there is another function called “namaste” for this function the global value is again changed and now global value is  local value of x from previous function which is x=”hui” because “namaste” is nested function for “howdy” function and its take global value from enclosed scope and enclosed scope for nested function is previous function and for this function enclosed scope is “howdy” function values. when we modify x value x=”po” now local value of x is “po” for this function ‘s local namespace and global value for this function is x=”hui” but local value for this function x=”po” is global value for next nested function of “namaste” function.

At last function is “welcome” function which is nested under “namaste” function so for this global value is again changed and global value for this function is x=”po” because its taking global value from enclosed scope which is “namaste” for this function. so global value for this function is local value of previous function.

Nonlocal keyword:

as we know about global keyword there is another keyword which is called nonlocal keyword .

its global keyword but only and only for inside nested. its lifetime is inside nested functions.

let’s talk about this :

if we try to use nonlocal as global :

we will get error :

because nonlocal works only in enclosed scope or in nested functions.

if we try nonlocal same as parameter then it will raise error :

It means we can’t use parameter as nonlocal keyword.

now let’s try working program of nonlocal keyword:

take a look of these two programs :

one is without nonlocal keyword program :

output is :

now same program with nonlocal keyword :

output is :

can you see the difference between these two programs ? what’s the difference ?

different is value of x , print function which is situated at outer sider of function its taking x value from enclosed scope (main function of nested function) but when we use nonlocal keyword it takes value of x print outside of function from the nested function instead of main function.

as you can see in first program outside print(which is defined after function exist) is taking x value hello() but when we use nonlocal print is taking value from hellooo() function.

if you are thinking “op” x should print x=12 then can be wrong because we have defined x=1111 as nonlocal which will work global for nested functions.

output would be :

Now let’s talk about Built-in scope:

 

 

Built-in scope:

Built-in are the functions which are defined already in python , we don’t have to define those functions we can use those functions by passing argument in those function to call the functions.

 

let’s understand this program:

output is :

when you execute this program , it gives the length of the string . How it calculated the length of the string ? we never defined any function called length and we just passed argument in len() and we get the length of string. Here len() is built-in function and when we call len() then program first will look for local namespace for len if it not found then it will look enclosed namespace and then again if not found then it will look global and if not found in global then it will search in built-in namespace.There are 68 built-in functions defined in Python 3.5.2 version.

Now let’s do something more and define own len function to overwrite the built-in len function and let’s see what it will do:

it will print :

we defined our own len() function and we know there is len() in built-in but when it will find len() in global namespace then it will not search in built-in namespace.

Since the exact same names can be used to map names to different objects – as long as the names are in different name spaces – there is no problem of reusing the name len to define our own length function (this is just for demonstration pruposes, it is NOT recommended). As we go up in Python’s  L -> E -> G -> B hierarchy, the function a_func() finds len() already in the global scope (G) first before it attempts to search the built-in (B) namespace.

Import methods in python :

There are three methods to import modules in program:

if we want to import pi then :

import math
from math import pi
from math import *

difference between first and second is you have to use math prefix with every function of math like math.pi but from second method you don’t have to use math prefix and third method import all function of math in current program so also don’t need to use math prefix.

1. import SomeModule

This is the simplest way to do imports and generally recommended. You get access to the module’s namespace provided you use the module’s name as a prefix. This means that you can have names in your program which are the same as those in the module, but you’ll be able to use both of them. It’s also helpful when you’re importing a large number of modules as you see which module a particular name belongs to.

2. from SomeModule import SomeName

This imports a name (or a few, separated by commas) from a module’s namespace directly into the program’s. To use the name you imported, you no longer have to use a prefix, just the name directly. This can be useful if you know for certain you’ll only need to use a few names. The downside is that you can’t use the name you imported for something else in your own program. For example, you could use add() instead of Integer.add(), but if your program has an add() function, you’ll lose access to the Integer’s add() function.

3. from SomeModule import *

This imports all the names from SomeModule directly into the module’s namespace. Generally not a good idea as it leads to ‘namespace pollution’. If you find yourself writing this in your code, you should be better off with the first type of import.

These imports apply to classes and other data just as much as functions. Imports can be confusing for the effect they have on the namespace, but exercising a little care can make things much cleaner.

3 comments

Leave a Reply

Your email address will not be published. Required fields are marked *