Python 3 Deep Dive Part 4 Oop

Python avoids traditional explicit getter and setter methods ( get_value() / set_value() ) in favor of properties. Properties let you wrap attribute access behind function logic while maintaining clean dot-notation syntax. The Underlying Descriptor Protocol

"Pythonic" OOP relies heavily on "dunder" (double underscore) methods. These hooks allow your objects to behave like built-in types (lists, dicts, ints, strings).

[ Metaclass: type ] │ (Constructs the class object) ▼ [ Class Namespace: CourseSection ] ───► Contains Descriptors, Functions, Class Variables │ (Instantiates via __new__ & __init__) ▼ [ Instance Namespace: course_obj ] ───► Contains Bound Methods, Instance Variables

In the Deep Dive (Part 4), we discover the "Old Magic": . These are objects that manage the attributes of other objects. When you use the @property decorator, you are actually using a simplified version of a descriptor.

You rarely need to override __new__ , but it is vital when working with immutable data types or implementing structural design patterns like the Singleton pattern. python 3 deep dive part 4 oop

class D(B, C): def process(self): print("D process") super().process()

class Bad: def __init__(self, items=[]): self.items = items # Shared across all instances!

def __iter__(self): return iter(self._items.values())

Python is duck-typed, but ABCs allow you to define and enforce method implementation. Python avoids traditional explicit getter and setter methods

Returns a clean, user-friendly string presentation. Used by print() . __repr__

Combine several OOP concepts: ABCs, metaclass auto-registration, and descriptors.

@property def year(self): return self._year

class Demo: @classmethod def c_meth(cls): return cls @staticmethod def s_meth(): return "No bindings" Use code with caution. 3. Properties and Encapsulation These hooks allow your objects to behave like

Every class you define is an instance of a metaclass. By default, that metaclass is type .

instructor = Speaker() print(type(instructor.say_hello)) # Output: Use code with caution. The Magic Behind self Injection

print(isinstance(5, object)) # True print(isinstance(int, object)) # True print(isinstance(object, type)) # True (object is an instance of type) print(isinstance(type, object)) # True (type is an instance of object)

Descriptors are the powerful, seldom-visible mechanism that powers properties, static methods, class methods, and the super() lookup. An object is a if its class implements any of the methods __get__() , __set__() , or __delete__() .