14.5. Function Scope
Values defined in function does not leak out
Functions has access to global values
Shadowing is when you define variable with name identical to the one from outer scope
After function return, the original value of a shadowed variable is restored
global
keyword allows modification of global variableUsing
global
keyword is considered as a bad practice
In Python, a function scope refers to the area of a program where a variable is accessible. A variable's scope is determined by where it is defined in the program.
When a variable is defined inside a function, it has local scope, which means that it can only be accessed within that function. Local variables are destroyed when the function returns.
Here's an example of using local variables in Python:
>>> def login():
... authenticated = True
... print(authenticated)
>>>
>>> login()
True
>>>
>>> print(authenticated)
Traceback (most recent call last):
NameError: name 'authenticated' is not defined
In this example, the authenticated
variable is defined inside
the login()
function. It has local scope and can only be accessed
within the function. When the function is called, it prints the value
of authenticated
. When the function returns, the authenticated
variable is destroyed.
If we try to access the authenticated
variable outside the function,
we get a NameError
because the variable is not defined in the global
scope.
Variables defined outside of any function have global scope, which means that they can be accessed from anywhere in the program. Global variables are not destroyed when a function returns.
Here's an example of using global variables in Python:
>>> authenticated = True
>>>
>>> def login():
... print(authenticated)
>>>
>>> login()
True
>>>
>>> authenticated
True
In this example, the authenticated
variable is defined outside of any
function and has global scope. It can be accessed from within the login()
function and from outside the function. When the function is called,
it prints the value of authenticated
. When the program ends, the
authenticated
variable is not destroyed because it has global scope.
Using function scope helps to keep variables organized and prevent naming conflicts between different parts of a program.
14.5.1. Globals
globals()
returns a dictionary containing the global variablesEach variable in the dictionary is a key-value pair where the key is the variable name and the value is the variable value
>>> 'authenticated' in globals()
False
>>>
>>> authenticated = True
>>>
>>> 'authenticated' in globals()
True
14.5.2. Locals
locals()
returns a dictionary containing the variables defined in the current scopelocals()
is useful for debugging and introspection
>>> def login(username, password=None):
... authenticated = False
... print(locals())
>>>
>>>
>>> login('mwatney')
{'username': 'mwatney', 'password': None, 'authenticated': False}
14.5.3. Local Scope
Values defined in function does not leak out
>>> authenticated
Traceback (most recent call last):
NameError: name 'authenticated' is not defined
>>>
>>> def login():
... authenticated = True
... print(authenticated)
>>>
>>> authenticated
Traceback (most recent call last):
NameError: name 'authenticated' is not defined
>>>
>>> login()
True
>>>
>>> authenticated
Traceback (most recent call last):
NameError: name 'authenticated' is not defined
14.5.4. Global Scope
Functions has access to global values
>>> authenticated = False
>>>
>>> def login():
... print(authenticated)
>>>
>>> authenticated
False
>>>
>>> login()
False
>>>
>>> authenticated
False
14.5.5. Shadowing
When variable in function has the same name as in outer scope
Shadowing in a function is valid only in a function
Shadowed variable will be deleted upon function return
After function return, the original value of a shadowed variable is restored
>>> authenticated = False
>>>
>>> def login():
... authenticated = True
... print(authenticated)
>>>
>>> authenticated
False
>>>
>>> login()
True
>>>
>>> authenticated
False
14.5.6. Assignments
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Function Scope Locals
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% English
# 1. Modify function `run`
# 2. Calling function should print value of local variables `a` and `b`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj funkcję `run`
# 2. Wywołanie funkcji powinno wypisać wartość zmiennych lokalnych `a` i `b`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isfunction
>>> assert run is not Ellipsis, \
'Write solution inside `run` function'
>>> assert isfunction(run), \
'Object `run` must be a function'
>>> run()
a=1, b=2
"""
# Calling function should print value of local variables `a` and `b`
# type: Callable[[], None]
def run():
a = 1
b = 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Function Scope Globals
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% English
# 1. Modify function `run`
# 2. Calling function should print value of global variables `a` and `b`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj funkcję `run`
# 2. Wywołanie funkcji powinno wypisać wartość zmiennych globalnych `a` i `b`
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isfunction
>>> assert run is not Ellipsis, \
'Write solution inside `run` function'
>>> assert isfunction(run), \
'Object `run` must be a function'
>>> run()
a=1, b=2
"""
a = 1
b = 2
# Calling function should print value of global variables `a` and `b`
# type: Callable[[], None]
def run():
...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: Function Scope Locals
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% English
# 1. Modify function `run` with local variables `a=1` and `b=2`
# 2. Return `dict` with variable names and their values,
# example: {'a': 1, 'b': 2}
# 3. Use `locals()` function
# 6. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj funkcję `run` z lokalnymi zmiennymi `a=1` i `b=2`
# 2. Zwróć `dict` z nazwami zmiennych i ich wartościami,
# przykład: {'a': 1, 'b': 2}
# 3. Użyj funkcji `locals()`
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isfunction
>>> assert run is not Ellipsis, \
'Write solution inside `run` function'
>>> assert isfunction(run), \
'Object `run` must be a function'
>>> run()
{'a': 1, 'b': 2}
"""
# Return `dict` with variable names and its values, example: {'a': 1, 'b': 2}
# Use `locals()` function
# type: Callable[[], dict[str,int]]
def run():
a = 1
b = 2
return ...