Descriptors control attribute access through __get__, __set__, __delete__ methods. Used in properties, methods, class attributes. Enable reusable attribute behavior. Example: implementing validation, computed attributes, or attribute access logging.
Method overriding redefines method from parent class in child class. Used to specialize behavior while maintaining interface. Call parent method using super() when needed. Example: overriding __str__ for custom string representation.
Override special methods for operators: __add__ for +, __eq__ for ==, etc. Enable class instances to work with built-in operators. Example: implement __lt__ for sorting. Consider reverse operations (__radd__, etc.).
Dataclasses (@dataclass) automatically add generated methods (__init__, __repr__, etc.). Used for classes primarily storing data. Support comparison, frozen instances, inheritance. More concise than manual implementation.
A class is a blueprint for objects, defining attributes and methods. An object is an instance of a class. Classes define structure and behavior, while objects contain actual data. Example: class Dog defines properties like breed, while a specific dog object represents an actual dog with those properties.
Inheritance allows a class to inherit attributes and methods from another class. Implemented using class Child(Parent). Supports single, multiple, and multilevel inheritance. Example: class Car(Vehicle) inherits from Vehicle class. Use super() to access parent class methods.
Magic methods control object behavior for built-in operations. Examples: __init__ for initialization, __str__ for string representation, __len__ for length, __getitem__ for indexing. Enable operator overloading and customize object behavior.
Polymorphism implemented through method overriding in inheritance and duck typing. Same method name behaves differently for different classes. No need for explicit interface declarations. Example: different classes implementing same method name but different behaviors.
Multiple inheritance allows class to inherit from multiple parents: class Child(Parent1, Parent2). MRO determines method lookup order using C3 linearization algorithm. Access MRO using Class.__mro__. Handle diamond problem through proper method resolution.
Composition creates objects containing other objects as parts (has-a relationship), while inheritance creates is-a relationships. Composition more flexible, reduces coupling. Example: Car has-a Engine vs. ElectricCar is-a Car.
super() returns proxy object for delegating method calls to parent class. Handles multiple inheritance correctly using MRO. Used in __init__ and other overridden methods. Example: super().__init__() calls parent's __init__.
__new__ creates instance, called before __init__. __init__ initializes instance after creation. __new__ rarely overridden except for singletons, immutables. __new__ is static method, __init__ is instance method.
Implement __enter__ and __exit__ methods. __enter__ sets up context, __exit__ handles cleanup. Used with 'with' statement. Alternative: @contextmanager decorator for function-based approach.
Use pickle for Python-specific serialization, implement __getstate__/__setstate__ for custom serialization. Consider JSON serialization with custom encoders/decoders. Handle security implications of deserialization.
Python uses name mangling with double underscore prefix (__var) for private attributes. Single underscore (_var) for protected attributes (convention). No true private variables, but follows 'we're all consenting adults' philosophy. Access control through properties and descriptors.
Properties (@property decorator) provide getter/setter functionality with attribute-like syntax. Control access to attributes, add validation, make attributes read-only. Example: @property for getter, @name.setter for setter. Used for computed attributes and encapsulation.
Metaclasses are classes for classes, allow customizing class creation. Created using type or custom metaclass. Used for API creation, attribute/method validation, class registration, abstract base classes. Example: ABCMeta for abstract classes.
Class variables shared among all instances (defined in class), instance variables unique to each instance (defined in __init__). Class variables accessed through class or instance, modified through class. Be careful with mutable class variables.
Implement using metaclass, __new__ method, or module-level instance. Control instance creation, ensure single instance exists. Handle thread safety if needed. Example: override __new__ to return existing instance or decorator approach.
Use __getattr__, __setattr__, __getattribute__, __delattr__ for custom attribute access. __getattr__ called for missing attributes, __getattribute__ for all attribute access. Be careful with infinite recursion.
Use __slots__, @property with only getter, override __setattr__/__delattr__. Store data in private tuples, implement __new__ instead of __init__. Consider frozen dataclasses. Make all instance data immutable.
__str__ for human-readable string representation, __repr__ for unambiguous representation (debugging). __repr__ should be complete enough to recreate object if possible. Default to __repr__ if __str__ not defined.
Mixins are classes providing additional functionality through multiple inheritance. Used for reusable features across different classes. Keep mixins focused, avoid state. Example: LoggerMixin for adding logging capability.
__dict__ stores instance attributes in dictionary. Enables dynamic attribute addition. Not present when using __slots__. Accessed for introspection, serialization. Consider memory implications for many instances.
Instance methods (default) have self parameter, access instance data. Class methods (@classmethod) have cls parameter, access class data. Static methods (@staticmethod) have no special first parameter, don't access class/instance data. Each serves different purpose in class design.
Use abc module with ABC class and @abstractmethod decorator. Abstract classes can't be instantiated, enforce interface implementation. Example: from abc import ABC, abstractmethod. Used for defining common interfaces and ensuring implementation.
__slots__ restricts instance attributes to fixed set, reduces memory usage. Faster attribute access, prevents dynamic attribute addition. Trade flexibility for performance. Used in classes with fixed attribute set.
Class decorators modify or enhance class definitions. Applied using @decorator syntax above class. Can add attributes, methods, or modify class behavior. Example: dataclass decorator for automatic __init__, __repr__.
Implement container protocol methods: __len__, __getitem__, __setitem__, __delitem__, __iter__. Optional: __contains__, __reversed__. Consider collections.abc base classes. Example: custom list or dictionary implementation.