0% found this document useful (0 votes)
22 views25 pages

Lecture 25-26 - Global and Local Scopes

Uploaded by

f2019065117
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views25 pages

Lecture 25-26 - Global and Local Scopes

Uploaded by

f2019065117
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 25

Scopes And Namespaces

When an object is assigned to a variable a = 10

that variable points to some object

and we say that the variable (name) is bound to that object

That object can be accessed using that name in various parts of our code But not just

anywhere!

That variable name and it's binding (name and object) only "exist" in specific parts of our
code

the portion of code where that name/binding is defined, is called the lexical scope of the variable these bindings are

stored in namespaces

(each scope has its own namespace)


The Global Scope
The global scope is essentially the module scope.

It spans a single file only.

There is no concept of a truly global (across all the modules in our entire app) scope in Python. The only

exception to this are some of the built-in globally available objects, such as:

True False None dict print

The built-in and global variables can be used anywhere inside our module including

inside any function


Global Scopes Are Nested Inside The Built-in Scope

Built-in Scope name space


name
var1 0xA345E
space
Module1 func1 0xFF34A
Scope name
space

Module2
Scope name
space

If you reference a variable name inside a scope and Python does not find it in that scope's namespace it will
look for it in an enclosing scope's namespace
Examples
module1.py Python does not find True or print in the current (module/global) scope So, it looks for
print(True) them in the enclosing scope →built-in
Finds them there → True

module2.py Python does not find a or print in the current (module/global) scope
print(a) So, it looks for them in the enclosing scope →built-in

Find print, but not a →run-time Name Error


module3.py
print = lambda x: 'hello {0}!'.format(x)

s = print('world') Python finds print in the module scope


So it uses it!
s →hello world!
The Local Scope
When we create functions, we can create variable names inside those functions (using assignments)

e.g. a = 10

Variables defined inside a function are not created until the function is called

Every time the function is called, a new scope is created

Variables defined inside the function are assigned to that scope → Function Local scope
→ Local scope

The actual object the variable references could be different each


time the function is called

(this is why recursion works!)


Example these names will considered local to
my_func
my_func a
def my_func(a, b): c = a * b
b return c c

my_func
a→ 'z'
my_func('z', 2) b→ 2
c→ same names, different local scopes
'zz'

my_func
my_func(10, 5) a→ 10
b→ 5
c→
50
Nested Scopes
Namespace lookups
Scopes are often nested When requesting the object bound to a variable name:
e.g. print(a)
Built-in Scope

Python will try to find the object bound to the variable


Module Scope

Local • in current local scope first


Local Scope
• works up the chain of enclosing scopes
Scope
Local
Scope
Example built-in scope
module1.py True

a = 10 a→ 10
global scope
def my_func(b): my_func
print(True) print(a)
print(b) local
b→ 300 local
scope b→ 'a'
scope
my_func(300)

my_func('a')

Remember reference counting?


When my_func(var) finishes running, the scope is gone too!
and the reference count of the object var was bound to (referenced) is decremented

We also say that var goes out of scope


Accessing the global scope from a local scope
When retrieving the value of a global variable from inside a function, Python automatically
searches the local scope's namespace, and up the chain of all enclosing scope namespaces

local → global → built-in

What about modifying a global variables value from inside the function?

a=0 assignment → Python interprets this as a local variable (at compile-time)


→ the local variable a masks the global variable a
def my_func():
a = 100 built-in
print(a)
global a→0
my_func() → 100
my_func

print(a) → 0 local
a→ 100
The global keyword

We can tell Python that a variable is meant to be scoped in the global scope by using the global keyword

a=0

def my_func(): global built-in


a
global
a = 100 a→ 0
my_func
my_func() print(a) →
local
100
Example

counter = 0

def increment():
global counter
counter += 1

increment()
increment()
increment()

print(counter) → 3
Global and Local Scoping
When Python encounters a function definition at compile-time
it will scan for any labels (variables) that have values assigned to them (anywhere in the function) if the label has
not been specified as global, then it will be local

variables that are referenced but not assigned a value anywhere in the function will not be local, and Python will, at run-
time, look for them in enclosing scopes

a = 10 Assignment
def func4(): at compile time → a local
a is referenced only in entire function
at compile time → a non-local print(a) a =
def func1():
100
print(a)
assignment → when we call func4()
def func2(): a = at compile time → a local print(a) results in a run-time error
100
because a is local, and we are
referencing it before we have assigned
def func3(): assignment a value to it!
global a a = at compile time → a global
100 (because we told Python a was global)
Inner Functions
We can define functions from inside another function:

def outer_func(): # some global


code
local (outer_func) Nested local scopes
def inner_func():
# some code

inner_func()
local (inner_func)

outer_func()

Both functions have access to the global and built-in scopes as well as their respective local scopes

But the inner function also has access to its enclosing scope – the scope of the outer function That scope is neither

local (to inner_func) nor global – it is called a nonlocal scope


Referencing variables from the enclosing scope
Consider this example we have seen before:

module1.py a = 10

def outer_func():
print(a)

outer_func() When we call outer_func, Python sees the reference to a


Since a is not in the local scope, Python looks in the enclosing (global) scope
Referencing variables from the enclosing scope
Now consider this example:
module1.py

def outer_func():
a = 10

def inner_func():
print(a)

inner_func()

outer_func()

When we call outer_func, inner_func is created


and called

When inner_func is called, Python does not find a in the local (inner_func) scope So it looks for it in the

enclosing scope, in this case the scope of outer_func


Referencing variables from the enclosing scope
module1.py

a = 10

def outer_func():
def inner_func():
print(a)

inner_func()

outer_func()

When we call outer_func, inner_func is defined


and called

When inner_func is called, Python does not find a in the local (inner_func) scope So it looks for it in the
enclosing scope, in this case the scope of outer_func
Since it does not find it there either, it looks in the enclosing (global) scope
Modifying global variables
We saw how to use the global keyword in order to modify a global variable within a nested scope

a = 10

def outer_func1():
global a
a = 1000

outer_func1()
print(a) → 1000
We can of course do the same thing from within a nested function

def outer_func2(): def


inner_func():
global a
a = 'hello'
inner_func()
outer_func2()
print(a) → hello
Modifying nonlocal variables
Can we modify variables defined in the outer nonlocal scope?

def outer_func():
x = 'hello'
def inner_func():
x = 'python'
inner_func()

print(x)

outer_func() → hello

When inner_func is compiled, Python sees an assignment to x

So it determines that x is a local variable to inner_func

The variable x in inner_func masks the variable x in outer_func


Modifying nonlocal variables

Just as with global variables, we have to explicitly tell Python we are modifying a nonlocal variable We can do

that using the nonlocal keyword


def outer_func():
x = 'hello’

def inner_func():
nonlocal x
x = 'python'
inner_func()
print(x)

outer_func() → python
Nonlocal Variables
Whenever Python is told that a variable is nonlocal
it will look for it in the enclosing local scopes chain until it first encounters the specified variable
name
Beware: It will only look in local scopes, it will not look in the global scope
CS504 Software Engineering
def outer(): Virtual University of Pakistan · Playlist
x = 'hello' global
Virtual University of Pakistan · Playlist
Verified
def inner1(): • local (outer) inner1

def inner2(): • x
nonlocal x local (inner1)
inner2
x = 'python' inner2()
local (inner2)
x
inner1()
print(x)

outer() → python
Nonlocal Variables
But consider this example:
global
→ python
def outer():
x = 'hello' local (outer)→ montyx
def inner1():
x = 'python' local (inner1)
x
→ hello
def inner2():
nonlocal x local (inner2)
x = 'monty' x
print('inner(before)', x) inner2() → python
print('inner(after)', x)
→ monty

inner1() print('outer', x)
outer() → monty
Nonlocal Variables

def outer(): global


x = 'hello'
def inner1(): nonlocal x local (outer)
x = 'python' x
def inner2(): nonlocal x local (inner1) x
x = 'monty' local (inner2)
print('inner(before)', x) inner2()
x
print('inner(after)', x)
→ python

→ monty

inner1()
print('outer', x) → monty

outer()
Nonlocal and Global Variables
global
x = 100
def outer(): x
local (outer)
x = 'python' x
def inner1(): nonlocal x
local (inner1) x
x = 'monty'
def inner2(): local (inner2)
global x x
x = 'hello' print('inner(before)', x)
inner2()
print('inner(after)', x) → monty

→ monty
inner1()
print('outer', x) → monty
outer() print(x)
→ hello

You might also like