10.14. Functional Namespace
Functions provide namespaces
Only code inside that namespace can access it's locals
In Python, a function is a namespace, which means that it is a container for variables and other objects. The variables and objects defined within a function are only accessible within that function's namespace, and cannot be accessed from outside the function.
When a function is called, a new namespace is created for it. This namespace contains all the local variables and objects defined within the function, as well as any arguments passed to the function. The namespace is destroyed when the function returns.
Here's an example of using a function as a namespace in Python:
>>> def my_function():
... x = 10
... y = 20
... print(x + y)
>>>
>>> my_function()
30
>>> print(x)
Traceback (most recent call last):
NameError: name 'x' is not defined
In this example, the my_function()
function defines two variables
(x
and y
) within its namespace. These variables are only accessible
within the function. When the function is called, it prints the sum of x
and y
. When the function returns, the namespace is destroyed, and the
variables are no longer accessible.
If we try to access the x
variable outside the function, we get a
NameError
because the variable is not defined in the global namespace.
Using functions as namespaces helps to keep code modular and organized. It also helps to prevent naming conflicts between different parts of a program.
10.14.1. Variables Inside Function
Variables inside function
>>> def user():
... firstname = 'Mark'
... lastname = 'Watney'
10.14.2. Functions Inside Function
Functions inside function
>>> def user():
... def login():
... print('user login')
...
... def logout():
... print('user logout')
10.14.3. Functions and Variables
>>> def user():
... firstname = 'Mark'
... lastname = 'Watney'
...
... def login():
... print('user login')
...
... def logout():
... print('user logout')
10.14.4. Call
>>> def user():
... firstname = 'Mark'
... lastname = 'Watney'
...
... def login():
... print('user login')
...
... def logout():
... print('user logout')
>>> user()
10.14.5. Return Variable
>>> def user():
... firstname = 'Mark'
... lastname = 'Watney'
...
... def login():
... print('user login')
...
... def logout():
... print('user logout')
...
... return firstname
>>> user()
'Mark'
10.14.6. Return Results
>>> def run():
...
... def get_hello():
... return 'Hello'
...
... def get_goodbye():
... return 'Goodbye'
...
... return get_hello()
>>>
>>>
>>> run()
'Hello'
>>> def run():
...
... def get_hello():
... return 'Hello'
...
... def get_goodbye():
... return 'Goodbye'
...
... return get_hello(), get_goodbye()
>>>
>>>
>>> run()
('Hello', 'Goodbye')
10.14.7. Return Function
>>> def run():
... def say_hello():
... print('Hello')
...
... def say_goodbye():
... print('Goodbye')
...
... return say_hello
>>>
>>>
>>> hello = run()
>>> hello()
Hello
>>> def run():
... def say_hello():
... print('Hello')
...
... def say_goodbye():
... print('Goodbye')
...
... return say_hello, say_goodbye
>>>
>>>
>>> hello, goodbye = run()
>>>
>>> hello()
Hello
>>>
>>> goodbye()
Goodbye
>>> def run():
... class Admin:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
...
... return Admin('Mark', 'Watney')
>>>
>>>
>>> mark = run()
>>>
>>> vars(mark)
{'firstname': 'Mark', 'lastname': 'Watney'}
10.14.8. Locals
>>> def run():
... firstname = 'Mark'
... lastname = 'Watney'
...
... def say_hello():
... print('Hello')
...
... def say_goodbye():
... print('Goodbye')
...
... class Admin:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
...
... class Guest:
... def __init__(self, firstname, lastname):
... self.firstname = firstname
... self.lastname = lastname
...
... mark = Admin('Mark', 'Watney')
... melissa = Guest('Melissa', 'Lewis')
...
... print(locals())
>>> run()
{'firstname': 'Mark',
'lastname': 'Watney',
'say_hello': <function run.<locals>.say_hello at 0x...>,
'say_goodbye': <function run.<locals>.say_goodbye at 0x...>,
'Admin': <class '__main__.run.<locals>.Admin'>,
'Guest': <class '__main__.run.<locals>.Guest'>,
'mark': <__main__.run.<locals>.Admin object at 0x...>,
'melissa': <__main__.run.<locals>.Guest object at 0x...>}
10.14.9. 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: Functional Closure Define
# - Difficulty: easy
# - Lines: 4
# - Minutes: 3
# %% English
# 1. Define function `check` with `func: Callable` as a parameter
# 2. Define closure function `wrapper` inside `check`
# 3. Function `wrapper` takes `*args` and `**kwargs` as arguments
# 4. Function `wrapper` returns `None`
# 5. Function `check` must return `wrapper: Callable`
# 6. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcję `check`, z `func: Callable` jako parametr
# 2. Zdefiniuj funkcję closure `wrapper` wewnątrz `check`
# 3. Funkcja `wrapper` przyjmuje `*args` i `**kwargs` jako argumenty
# 4. Funkcja `wrapper` zwraca `None`
# 5. Funkcja `check` ma zwracać `wrapper: Callable`
# 6. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> assert callable(check)
>>> assert callable(check(lambda:...))
>>> result = check(lambda:...).__call__()
>>> result is None
True
"""
# Takes func
# Defines wrapper with args, kwargs
# Returns wrapper
# type: Callable[[Callable], Callable]
def check():
...