Busca en todas las páginas de la documentación
346 pages across 50 sections. 3601 questions total.
It means an entry mapping that name (a string) to that object now exists in some namespace - a dictionary-like structure such as a module's globals, a function's locals, or a class body.
Because assignment never copies data - it only creates or updates a name-to-object binding, so x and y end up pointing at the same object when the right-hand side is already an object reference.
It is the fixed order Python searches when resolving a bare name: Local (the current function frame), Enclosing (any outer function frames), Global (the module's namespace), and Built-in (Python's built-in names like len or print).
If the function body assigns to that name anywhere, Python treats it as local for the entire function, so reading it before that assignment fails - global or nonlocal are needed to rebind an outer name instead of shadowing it.
Functionally, yes - a module object's namespace (everything you can access as module.name) is backed by a dictionary that's populated by running the module's top-level code once.
Python runs the module's top-level code only the first time; every subsequent import anywhere in the same process retrieves the identical cached module object from sys.modules rather than re-executing anything.
Because a def statement runs its default-value expressions exactly once and stores the resulting object on the function - every call that omits that argument reuses the same object, so mutating it accumulates state across calls.
A mapping from names to objects - in practice, most namespaces (module globals, function locals, class bodies) are implemented as dictionaries you can inspect with globals(), locals(), or vars().
Yes - CPython compiles source into bytecode first, then a virtual machine executes that bytecode frame by frame; that's why it's usually described as interpreted even though a real compilation step happens.
The Global Interpreter Lock (GIL) serializes bytecode execution to keep reference counting safe without needing a lock around every single object; Python 3.13+ offers an experimental free-threaded build that removes this constraint at the cost of extra per-object locking overhead.
Primarily through reference counting - the moment an object's reference count reaches zero it is freed immediately - with a periodic cyclic garbage collector handling the rarer case of objects that reference each other in a cycle.
Because scoping rules, shared-mutation bugs, import caching behavior, and the mutable-default trap are all separate-looking symptoms of the exact same underlying mechanism, so understanding the mechanism once explains all of them instead of memorizing four unrelated rules.
Generally yes - expressions are evaluated once at runtime with less overhead. Prefer f-strings for new code.
Network protocols, binary file formats, and crypto digests operate on bytes. Convert at the boundary.
UTF-8 for text files, HTTP JSON, and logs unless a spec mandates otherwise.
Use triple quotes: f"""line1\n{name}""". Newlines in the literal are preserved.
r"\\server\share" treats backslashes literally - handy for regex and Windows paths in docs.
f"{1_000_000:,}" produces 1,000,000. Underscores in literals are cosmetic for readability too.
Yes: f"{len(items)} items". Keep expressions simple for readability.
str.strip removes only ends. For all occurrences use replace or re.sub.
Aggressive case normalization for comparisons - better than lower() for Unicode matching.
Never interpolate user input. Use parameterized queries from your DB driver or ORM.
When branching on structure - typed dict keys, tuple arity, or class attributes. Stick to if for simple booleans.
The else block runs after the loop completes without hitting break. Useful for search loops.
Use a flag, extract to a function with return, or in 3.11+ structured exception patterns sparingly.
Class patterns use isinstance semantics; literals use equality. Sequence patterns match structure and length.
and/or stop evaluating once the result is determined - use for guard clauses like obj and obj.method().
enumerate(items, start=0) - cleaner than manual counter variables.
Yes - case MyClass(attr=value): matches instances with attributes. Dataclasses work well here.
continue jumps to next iteration. pass is a no-op placeholder in syntax-required blocks.
Include case None: or use guards. Combine with type hints and narrowing in static checkers.
Rare in application code. for/else for search is more idiomatic; prefer functions over clever loop else.
Yes: [x if x > 0 else 0 for x in nums] - expression before for, not the same as loop else.
Often yes in CPython - optimized bytecode and no repeated method lookup for append.
When data may not fit in memory or you only pass through once to aggregate functions.
No in Python 3 - x in [x for x in items] is local to the comprehension.
[y for row in matrix for y in row] - multiple for clauses flatten one level.
{k: v for k, v in zip(keys, values)} - or dict(zip(keys, values)) when no filter needed.
{expr for x in items} - curly braces without colon. Produces a set, not dict.
Yes when reusing the pipeline definition: gen = (x for x in data if pred(x)) then pass to functions.
Expand to a for loop temporarily, or extract the inner expression to a named function.
Not always - map with an existing function can be clearer. Comps win for inline transforms with filters.
Name lookup order: Local, Enclosing (nested outer functions), Global (module), Built-in namespace.
To mark following parameters as keyword-only: def f(a, *, b=1) forces f(1, b=2).
Separates positional-only parameters: def f(a, b, /, c) - a and b cannot be passed by keyword.
*args collects extra positionals as tuple; **kwargs collects extra keywords as dict. Order in signature matters.
Yes at function definition time - why mutable defaults are shared. Immutable defaults (int, str, tuple) are safe.
When a nested function must rebind a variable in an enclosing function - counters, accumulators in closures.
Yes: def f(*args: int) or *args: int with TypedDict patterns in advanced typing - see type hints section.
Single expression only - no statements. Use def for anything non-trivial.
def wrapper(*args, **kwargs): return inner(*args, **kwargs) - common in decorators.
-> None documents no useful return. Omit only when obvious; mypy benefits from explicit None.
import module binds the module object. from module import name binds the name directly into the current namespace.
Regular packages yes (or implicit namespace package without it). Empty __init__.py is fine for marking a package.
Runs a module as __main__ with correct package metadata so relative imports work.
The directory containing the script or the current directory for -m. Editable installs add src to path via metadata.
Check package on PYTHONPATH, use absolute imports, verify pyproject.toml package discovery, reinstall editable.
Possible with path hacks - discouraged. Install package editable or configure proper layout instead.
Imports for type checkers only - avoids runtime circular import while keeping hints.
One dot is current package; two dots is parent. Requires package context - not in top-level scripts.
Rarely - sometimes in __init__.py re-export APIs with explicit __all__. Never in application modules.
Multiple directories contribute to one package name without a single __init__.py - used for plugin ecosystems.
Prefer pathlib for new code - readable operators and high-level read/write helpers.
with path.open("a", encoding="utf-8") as fh: fh.write(line + "\n")
"rb" and "wb" - never decode images as UTF-8 text.
for p in Path("src").rglob("*.py"): print(p)
Write temp in same filesystem directory, then Path.replace - readers see old or new file, never partial.
Catch FileNotFoundError or check path.exists() when optional config is acceptable.
No - read text then json.loads. Or use json.load with an open file handle.
strict for validated pipelines; replace or backslashreplace for lossy log ingestion only.
path.stat().st_size without reading contents.
Yes - context manager protocol runs __exit__ and closes the file even when an error propagates.
With uv run, no. For plain python/pip commands, activate or use full path .venv/bin/python.
.venv/, __pycache__/, .pytest_cache/, local .env files with secrets.
uv for new projects - faster installs and lockfiles. pip inside venv is fine for tiny scripts.
Delete .venv, run uv sync or uv venv && uv pip install -r requirements.txt.
Yes - .venv is convention. Update IDE interpreter path accordingly.
Use pyenv, uv python pin 3.14, or CI matrix python-version: "3.14".
Installs dependencies exactly from uv.lock - reproducible clones and CI.
PEP 668 protects system Python. Create a venv instead of pip install globally.
uv add --dev ruff mypy pytest - keeps tools out of production dependency sets when configured.
Yes by default with python -m venv. uv manages pip-compatible installs in its environments.
No - configure ruff and focus on readability. Automate formatting debates away.
Module-level constants and cached read-only config are fine. Mutable globals complicate tests - prefer injection.
Optional for throwaway scripts. Add them when the script grows or becomes a package.
match for structure (dict keys, typed events). if for simple scalar conditions.
This cookbook pins uv 0.6+ as the default fast path. Poetry remains valid for teams already standardized on it.
Start with new modules at strict optional flags; widen gradually. Pydantic models at HTTP boundaries first.
Better for map/filter transforms. Use a for loop when side effects or complex branching dominate.
print is fine for CLI UX. Services should use logging with structured fields - see errors-logging section.
Explicit comparisons (is None, len(x) == 0) when falsy-but-valid values like 0 matter.
Isolated environments with locked dependencies - everything else fails without reproducible installs.
Both terms appear in docs. Practically: names bind to object references. There are no C-style variables holding raw values on the stack for arbitrary objects.
Both names reference the same list object. Assignment never clones unless you explicitly copy.
No. Use mypy, pyright, or Pydantic when you need enforcement. Hints are stored in __annotations__ but ignored by the interpreter.
type(x) is int fails for subclasses. Prefer isinstance(x, int) for polymorphic checks.
Only if you mutate a shared mutable object. Rebinding a parameter name does not affect the caller's name.
Immutable objects are hashable (when contents are hashable) and safe as dict keys. They also prevent accidental in-place mutation via aliases.
from copy import deepcopy
clone = deepcopy(nested)Debugging identity issues - confirming whether two names point at the same object during troubleshooting.
Yes. Small integers may be cached, but semantically += on immutables rebinds the name to a new object.
When the type is not obvious from the assignment, or when mypy needs help narrowing unions.
Binary floats cannot represent 0.1 exactly. The sum is close but not identical - use isclose or Decimal.
Decimal for currency and anywhere humans expect base-10 rounding. float for science, ML, and performance.
Objects define truth via __bool__ or __len__. Empty containers and zero numbers are falsy; most other objects are truthy.
from decimal import Decimal, ROUND_HALF_UP
Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)It floors: -7 // 3 is -3 because floor(-2.33) is -3.
bool subclasses int. isinstance(True, int) is True, but use bools only for logic, not counting.
Wrap int() / Decimal() in try/except ValueError, or validate with a schema library at API boundaries.
Returns (a // b, a % b) in one call - common for paging and clock arithmetic.
Yes in Python 3 - practical limit is memory. Crypto and bigint math rely on this.
They operate on integer bit patterns - useful for flags, masks, and low-level protocols.