#!/usr/bin/env python # coding: utf-8 # # Class and Instance # # # ## namespace # The attributes of a namespace are usually implemented as dict # # - **`__class__`**: The link to its class (instance) # - **`__bases__`**: A tuple of references to their superclasses (class) # In[1]: class Rec(object): pass rec = Rec() print(rec.__class__) print(Rec.__bases__) # ## Class Object (Default Behavior) # 1. Assignments inside **class** make class attributes # 3. Class Attributes provid object state and behavior # # Classes are objects in their own right, even without instance # In[2]: class Rec(object): pass print(Rec) # ## Instance Object (Concrete Items) # Assignments to attributes of **self** in methods make per-instance attribues # ## Attribute # - When looking for a name, Python checks the instance, then its class, then all superclasses # - Each *object.attribute* reference invokes a new, independent search. # --- # # Operator Overloading # - Methods named with double underscores(**`__x__`**) # - Not built-in or reserved words, just attributes # - Can be called directly by your code # - e.g. **`x.__init__`** is often called manually to trigger initialization in a superclass # - Classes may override most built-in type operations # - No defaults for operator overloading methods # - Not are required # - New-style classes (detail in next chapter) have some defaults, but not for commom operations # # - It's an optinal feature. # - Used primarily by people developing tools for other Python programmers, not by application developers # - Overloaded operators should work the same way that built-in operator # # ## Why Operator Overloading? # - Mathematical in nature # - Expect the operators available on a built-in type like a list or a dict # - Mimic the built-in types