26.7 Comparing Objects: __eq__, __lt__, and @total_ordering

The Need for Custom Comparisons By default, Python’s == and != operators for objects compare their identities—that is, they check if two variables refer to the exact same object in memory, behaving like the is operator. This is rarely the desired behavior for data-centric classes. For instance, two distinct BankAccount objects with the same account number and balance should be considered equal for most application logic, even though they are separate instances. To enable this value-based comparison, you must provide your own implementation by defining the __eq__ method.

26.6 Object Lifecycle: Creation, __init__, and Destruction

The __init__ Method: The Object Constructor The __init__ method is the most fundamental and frequently used special method in Python. It is not technically a constructor—the actual object creation is handled by the __new__ method—but rather an initializer. After the __new__ method has created a new instance of the class, __init__ is automatically called to initialize the new object’s attributes and put it into a valid initial state. Its purpose is to ensure that every new object starts its life with the necessary data. The first parameter of __init__ is always self, which is a reference to the newly created instance being initialized. Subsequent parameters are used to pass initial values into the object.

26.5 The __dict__ of an Instance and a Class

In Python, every instance and class has a __dict__ attribute, which is a dictionary that stores its writable attributes. This mechanism is the primary way Python implements dynamic attribute storage for objects. Understanding __dict__ is crucial for comprehending how attribute lookup works, how memory is used, and how to perform advanced metaprogramming tasks. The Instance __dict__ When you create an instance of a class, Python allocates a new dictionary to store instance-specific attributes. This is the __dict__ you access directly from the instance. It is the first place the interpreter looks during attribute lookup on an instance.

26.4 String Representations: __str__ and __repr__

In Python, every object can have two distinct string representations: one for informal, human-readable output and another for formal, unambiguous debugging and development. These representations are provided by the __str__ and __repr__ special methods, respectively. Understanding the difference between them and implementing them correctly is crucial for creating robust, debuggable classes. The Core Distinction: str vs. repr The fundamental difference lies in their intended audience and purpose. The __str__ method is called by the str() built-in function and by the print() function. Its goal is to return a string that is “nicely printable” and easily understood by an end-user. It is meant to be informal and concise.

26.3 Methods: Instance, Class, and Static

In object-oriented programming, methods define the behaviors and actions that objects of a class can perform. Python provides three distinct types of methods, each with a different purpose, scope, and relationship to the class and its instances. Understanding the distinction between them is crucial for designing well-structured, efficient, and maintainable code. Instance Methods The most common type of method is the instance method. By default, any method defined inside a class is an instance method. Its defining characteristic is that its first parameter is always self, which is a reference to the specific instance of the class that called the method. Through self, the method can access and modify the instance’s attributes and call other instance methods.

26.2 Instance Attributes vs Class Attributes

In Python, both instance attributes and class attributes are fundamental to object-oriented programming, but they serve distinct purposes and behave differently. Understanding their distinction is crucial for designing robust and predictable classes. Definition and Basic Syntax An instance attribute is a variable that belongs to a specific, individual object (an instance) of a class. Its value is unique to that instance. You typically define instance attributes inside the __init__ method using self.

26.1 Defining a Class: class, __init__, and self

In Python, a class serves as a blueprint for creating objects. Objects are instances of a class, encapsulating both data (attributes) and behaviors (methods) that are logically related. The class keyword is the fundamental building block for this object-oriented paradigm, allowing you to define a new data type with its own specific structure and functionality. The class Keyword and Basic Structure The process of creating a new class begins with the class keyword, followed by the name of the class (by convention, using CamelCase) and a colon. The body of the class, indented beneath, contains all the method definitions that define the class’s behavior. The simplest possible class is one with no body at all, though it’s not particularly useful.

— joke —

...