Python Scope, First-Class Functions, *args,**kwargs & Mutable Default Arguments
Python has several concepts that look difficult at first, but they become simple once we understand what Python is actually doing. This guide covers: LEGB Scoping Rule Local, Enclosing, Global and Built-in scopes nonlocal First-Class Functions *args **kwargs Packing and Unpacking Mutable Default Argument Pitfall Safe ways to use default arguments 1. LEGB Scoping Rule What is Scope? Scope means…
Python provides several advanced concepts that may initially seem complex, but become easier to grasp once their underlying mechanism is understood. This guide explores: LEGB Scoping Rule, First-Class Functions, *args and **kwargs, Mutable Default Argument Pitfall, and Safe ways to use default arguments.
1. LEGB Scoping Rule: Python follows a specific search order to locate variables, known as the LEGB rule. The acronym stands for Local, Enclosing, Global, and Built-in scopes. Python stops searching once it finds the variable in the first applicable scope.
2. Local Scope: Variables defined inside a function are considered local variables. They can only be accessed within that function. An example:
def greet():
name = "Deepika"
print(name)
greet()
In this case, "name" is local to the greet() function and cannot be accessed outside of it. Attempting to do so results in a NameError.
3. Enclosing Scope: When a function is defined inside another function, it inherits the scope of the outer function. This is known as the enclosing scope. For example:
def outer():
name = "Deepika"
def inner():
print(name)
inner()
outer()
Here, "name" is in the enclosing scope of the inner function, not local to it. This concept is crucial for understanding closures.
4. Global Scope: Variables defined outside any functions typically reside in the global scope. They can be accessed throughout the module. For example:
name = "Deepika"
def greet():
print(name)
greet()
This will output "Deepika" because "name" is found in the global scope, not in the local scope of greet().
5. Built-in Scope: Python provides built-in functions like print(), len(), sum(), max(), min(), and type(). These are part of the built-in scope, and can be accessed directly without defining them within the script. For example:
numbers = [10, 20, 30]
print(len(numbers))
The "len" function is found in the built-in scope.
6. Mutable Default Argument Pitfall: Default argument values in function definitions are evaluated once when the function is defined, not each time the function is called. This can lead to unexpected behavior if mutable types like lists or dictionaries are used as default arguments. For example:
def append_item(item, my_list=[]):
my_list.append(item)
return my_list
print(append_item("a")) # Output: ['a']
print(append_item("b")) # Output: ['a', 'b']
The same list object gets modified in each function call, leading to unexpected results.
7. Safe ways to use default arguments: To avoid the mutable default argument pitfall, you can use None as a default value and create a new list inside the function if the argument is None. This ensures a fresh list is created for each function call.
def append_item(item, my_list=None):
if my_list is None:
my_list = []
my_list.append(item)
return my_list
This way, each function call gets its own list, avoiding the mutable default argument pitfall.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.