Methods like `__iter__`, `__next__`, `__call__`, `__eq__`, `__lt__`, and `__hash__` define how custom objects participate in loops, comparisons, hashing, and callable syntax.
- Iterators use `__iter__` and `__next__`
- Ordering and equality use rich comparison methods
- Hashing must stay consistent with equality
JSON is portable text, Pickle is Python-specific object serialization, and CSV is a simple tabular interchange format.
- JSON is safer and interoperable
- Pickle is not for untrusted data
- CSV needs clear delimiter and schema assumptions
Lists are mutable ordered sequences that support indexing, slicing, appending, extending, and in-place updates.
- Negative indices count from the end
- Slicing returns a new list
- append and extend do different things
Lists are mutable dynamic arrays; tuples are immutable ordered records.
- List can change
- Tuple is hashable if items are hashable
- Tuple signals fixed shape
Logging beats `print` for real systems because it supports levels, structured routing, timestamps, and configurable destinations.
- Levels include debug through critical
- Named loggers separate concerns
- Configuration controls formatting and handlers
`break` stops a loop, `continue` skips to the next iteration, `pass` is a placeholder, and loop `else` runs only if the loop did not break.
- Loop else is lesser known
- break changes whether else runs
- pass does nothing by itself
Python resolves imports through its module search path, and you can import names directly or alias modules for readability.
- `import x` and `from x import y` behave differently
- Aliases like `import numpy as np` are common
- Search path includes the current project and installed packages
Python's advanced model includes MRO, metaclasses, descriptors, duck typing, and the EAFP vs LBYL style trade-off.
- MRO defines lookup order
- Descriptors power managed attributes
- Duck typing focuses on behavior instead of exact types
Mutable objects can change in place; immutable objects require a new object for a changed value.
- List and dict are mutable
- str and tuple are immutable
- Matters for side effects and hashing
Nested dictionaries represent hierarchical data, and helper methods like `get`, `setdefault`, and `update` make access and merging cleaner.
- get avoids immediate KeyError
- setdefault initializes missing keys
- update merges another mapping in place
Nested lists make shallow copies especially important because the outer list may copy while inner lists still alias the same objects.
- Nested structures magnify aliasing bugs
- list() or slicing makes a shallow copy
- deepcopy is for fully independent nested state
Python lets you control how callers pass arguments so APIs can be both flexible and explicit.
- Positional-only uses `/`
- Keyword-only uses `*`
- Signature design affects readability