Functions and Scope Flashcards
6 cards from real Python practice questions. Tap to flip, then mark Knew It or Still Learning โ missed cards come back until you master them.
Read the first 6 Functions and Scope flashcards as text
A developer writes a function to log messages, intending for each call to start with a fresh list of tags unless specified. However, they notice that tags from previous calls are persisting. What is the most likely cause of this bug? ```python def log_message(message, tags=[]): tags.append('INFO') print(f"{message}: {tags}") log_message("System start") log_message("User login") ```
Answer: A mutable object (a list) is used as a default argument, which is evaluated only once when the function is defined.
In Python, default function arguments are evaluated once at the time the function is defined, not each time it is called. When a mutable object like a list or dictionary is used as a default argument, all calls to the function that don't provide a value for that argument will share the *same* object. In this case, the list `tags` is created once, and each subsequent call to `log_message` appends to the same list, leading to the accumulation of tags.
In Python's scope resolution, what is the LEGB rule?
Answer: The sequence Python follows to find a variable: Local, Enclosing, Global, Built-in.
The LEGB rule dictates the order in which Python searches for a name (variable, function, etc.). It checks scopes in the following order: 1. **L**ocal: The current function's scope. 2. **E**nclosing: The scope of any enclosing functions (in nested functions). 3. **G**lobal: The top-level module scope. 4. **B**uilt-in: The scope containing Python's built-in names like `print()` and `len()`.
What is the primary purpose of the `nonlocal` keyword in Python?
Answer: To allow an inner function to modify a variable from its nearest enclosing (but non-global) scope.
The `nonlocal` keyword is used inside nested functions. It indicates that a variable is not local to the inner function but belongs to the nearest enclosing function's scope. This allows the inner function to rebind or modify that variable directly, rather than creating a new local variable with the same name.
Consider the following code. What will be the output? ```python def multiplier_factory(n): def multiplier(x): return x * n return multiplier double = multiplier_factory(2) triple = multiplier_factory(3) print(double(5), triple(5)) ```
Answer: 10 15
This code demonstrates a closure. The `multiplier_factory` function returns another function, `multiplier`. The returned `multiplier` function "remembers" the value of `n` from the environment where it was created. When `multiplier_factory(2)` is called, it creates a function that remembers `n=2`. When `multiplier_factory(3)` is called, it creates a different function that remembers `n=3`. Therefore, `double(5)` returns 10 (5*2) and `triple(5)` returns 15 (5*3).
A programmer needs to modify a global variable from within a function. Which of the following code snippets correctly accomplishes this?
Answer: ```python count = 0 def increment(): global count count += 1 ```
To modify a variable in the global scope from within a function, you must explicitly declare your intent using the `global` keyword. Without it, Python would treat `count` as a new local variable within the `increment` function and raise an `UnboundLocalError` because it's being referenced before assignment. The `nonlocal` keyword is for modifying variables in an enclosing scope, not the global scope.
Which of the following statements about function arguments in Python is true?
Answer: Python uses a mechanism called 'pass-by-object-reference' or 'pass-by-assignment', where the function gets a copy of the reference to the object.
Python's argument passing mechanism is often described as 'pass-by-object-reference' or 'pass-by-assignment'. When you pass an argument, the function parameter becomes a new reference to the same object. If the object is mutable (like a list), changes made to it inside the function will affect the original object. If the object is immutable (like a number or string), reassigning the parameter inside the function creates a new local object, leaving the original unchanged. This behavior is distinct from pure pass-by-value or pass-by-reference.