Functions and Scope
Function definition patterns, argument shapes, and scope gotchas. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Busca en todas las páginas de la documentación
Function definition patterns, argument shapes, and scope gotchas. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Force callers to name options after * for clarity.
def connect(host: str, *, timeout: float = 5.0) -> str:
return f"{host}:{timeout}"
connect("db") # 'db:5.0'
connect("db", timeout=1.5) # 'db:1.5'
# connect("db", 1.5) # TypeError: positional after *Collect extra positional and keyword arguments for wrappers.
def show(*args, **kwargs):
return args, kwargs
show(1, 2, a=3) # ((1, 2), {'a': 3})Loop variables in closures bind late - capture with default args.
bad = [lambda: i for i in range(3)]
[f() for f in bad] # [2, 2, 2]
good = [lambda i=i: i for i in range(3)]
[f() for f in good] # [0, 1, 2]Decorators wrap callables; use functools.wraps to preserve metadata.
import functools
def twice(fn):
@functools.wraps(fn)
def wrapper(x):
return fn(fn(x))
return wrapper
@twice
def inc(x): return x + 1
inc(1) # 3
inc.__name__ # 'inc'Freeze some arguments of a callable for callbacks and maps.
from functools import partial
def power(base, exp): return base ** exp
square = partial(power, exp=2)
square(5) # 25Slash / marks positional-only parameters (3.8+).
def greyscale(r, g, b, /) -> float:
return 0.3 * r + 0.59 * g + 0.11 * b
greyscale(1, 0, 0) # 0.3
# greyscale(r=1, g=0, b=0) # TypeErrorNever use mutable defaults - use None and create inside.
def append_item(item, bucket: list | None = None) -> list:
if bucket is None:
bucket = []
bucket.append(item)
return bucket
append_item(1) # [1]
append_item(2) # [2] (not [1, 2])nonlocal rebinds enclosing function vars; global rebinds module vars - use sparingly.
def outer():
n = 0
def inc():
nonlocal n
n += 1
inc(); inc()
return n
outer() # 2Lambdas are single expressions - prefer def for multi-statement logic.
key = lambda row: row["score"]
key({"score": 10}) # 10
sorted([{"s": 2}, {"s": 1}], key=lambda r: r["s"])
# [{'s': 1}, {'s': 2}]Return tuples and unpack at the call site.
def divmod_safe(a: int, b: int) -> tuple[int, int]:
return a // b, a % b
q, r = divmod_safe(20, 3) # q=6, r=2First line summary; keep docs close to the function.
def normalize(text: str) -> str:
"""Return lowercase stripped text."""
return text.strip().lower()
normalize(" Hi ") # 'hi'
normalize.__doc__ # 'Return lowercase stripped text.'Memoize pure functions with an LRU cache.
from functools import lru_cache
@lru_cache(maxsize=256)
def fib(n: int) -> int:
return n if n < 2 else fib(n - 1) + fib(n - 2)
fib(10) # 55
fib.cache_info().hits # >= 0 after callsFunction overloading by type with singledispatch.
from functools import singledispatch
@singledispatch
def dump(x: object) -> str:
return str(x)
@dump.register
def _(x: int) -> str:
return f"int:{x}"
dump(3) # 'int:3'
dump(True) # 'int:True' (bool -> int register)
dump(1.5) # '1.5'Annotations are stored on __annotations__ - use typing.get_type_hints for evaluation.
def f(x: int) -> str: ...
f.__annotations__
# {'x': <class 'int'>, 'return': <class 'str'>}Any object with __call__ is callable - functions are just one kind.
class Adder:
def __call__(self, x: int) -> int:
return x + 1
add1 = Adder()
add1(4) # 5
callable(add1) # TrueStack versions: Python 3.14.0 (stable 3.14, maintenance 3.13) · uv 0.6+ · ruff 0.9+
Revisado por Chris St. John·Última actualización: 31 jul 2026