Attribute Handling Special Method Names
When we reference an attribute of an object with something like
someObject.name, Python uses several special methods to get
someAttr attribute of the object. Since we can
say things like
myObject.anAttr= 5, and
myObject.anAttr, there are actually three different implicit
methods related to attribute access.
When the attribute reference occurs on the left side of an
assignment statement, we are setting the attribute. When the attribute
occurs almost anywhere else were are getting the value of the attribute.
The final operation is deleting an attribute with the
While most attributes are simply instance variables, we have to
make a firm distinction between an
An attribute is a name, qualified by an object. It is a
syntactic construction. Generally, the attribute name is treated as
a key to access the object's internal collection of instance
__dict__. However, we can change the
behavior of an attribute reference.
An instance variable is stored in the
__dict__ of an object. Generally, we access
instance variables using attribute syntax. The attribute name is
simply the key of the instance variable in the object's
When we say
someObj.name, the default behavior is
There are several ways that we can tap into Python's internal
mechanisms for getting and setting attribute values.
The most accessible technique is to use the
property function to define get, set and delete
methods associated with an attribute name. The
property function builds descriptors for you.
We'll look at this in the section called “Properties”.
A slightly less accessible, but more extensible and reusable
technique is to define descriptor classes
yourself. This allows you considerable flexibility. You do this by
creating a class which defines get, set and delete methods, and you
associate this descriptor class with an attribute name. We'll look
at this in the section called “Descriptors”.
You can tap into Python's low-level special methods for
attribute access. There are three methods which plug into the
standard algorithm. The fourth method,
__getattribute__, allows you to change
attribute access in a fundamental way.
Changing attribute access can interfere with how people
understand the operation of your classes and objects. The default
assumption is that an attribute is an instance variable. While we can
fundamentally alter the meaning of a Python attribute, we need to be
cautious about violating the default assumptions of people reading our
Attribute Access Special Methods. Fundamentally, attribute access works through a few special
method names. Python has a default approach: it checks the object for
an instance variable that has the attribute's name before using these
attribute handling methods. Because Python uses these methods when an
attribute isn't an instance variable, you can easily create infinite
recursion. This can happen if you try to get an instance variable
using a simple
self.someAttr in the
__getattr__ method, or set the value of an
instance variable with a simple
self.someAttr in the
__setattr__ method. Within
__setattr__, you have to use the internal
These are the low-level attribute access methods.
Returns a value for an attibute when the name is not an
instance attribute nor is it found in any of the parent classes.
is the attribute name. This method
returns the attribute value or raises an
Assigns a value to an attribute.
is the attribute name,
is the value to assign to it.
Note that if you naively do self.name= value in this method, you
will have an infinite recursion of
__setattr__ calls. If you want to access
the internal dictionary of attributes,
__dict__, you have to use the following:
Delete the named attribute from the object.
is the attribute name.
Low-level access to a named attribute. If you provide this,
it replaces the default approach of searching for an attribute and
__getattr__ if the named
attribute isn't an instance variable of the class. To provide the
default approach, this method must explicitly evaluate the
__getattribute__ method with
. This only works for
classes which are derived from