Python in a Nutshell describes the lookup procedures when getting an attribute. The book distinguishes two cases
the lookup procedure when getting an attribute from a class, e.g.
cls.name
Getting an attribute from a class
When you use the syntax
C.name
to refer to an attribute on a class objectC
, the lookup proceeds in two steps:When
name
is a key inC.__dict__
,C.name
fetches the valuev
fromC.__dict__['name']
. Then, whenv
is a descriptor (i.e.,type(v)
supplies a method named__get__
), the value ofC.name
is the result of callingtype(v).__get__(v, None, C)
. Whenv
is not a descriptor, the value ofC.name is v
.When
name
is not a key inC.__dict__
,C.name
delegates the lookup toC
’s base classes, meaning it loops onC
’s ancestor classes and tries the name lookup on each (in method resolution order, as covered in “Method resolution order” on page 113).
the lookup procedure when getting an attribute from an instance, e.g.
obj.name
Since in Python 3, every class object is actually an instance of its metaclass (e.g. type
class), according to the book, why are the lookup procedure for getting an attribute from a class and the lookup procedure for getting an attribute from an instance different?