Python classes have a special inbuilt attribute called __dict__, which, as its name implies,
is a Python dictionary. This is used to store class attributes, including functions. The key
to access an entry in the dictionary is the name of the attribute (or function), and the
dictionary value is the value of the corresponding attribute (or a function reference). For
example, if we have:
class AminoAcid:
massDict = { … }
acceptableCodes = set(massDict.keys())
then AminoAcid.__dict__ would have an entry with key ‘massDict’ and one with key
‘acceptableCodes’. Note that the dictionary keys are Python strings.
Instances of objects also have an attribute called __dict__ , and this is used to store the
object’s own attributes. For example, if we have a class definition:
class Molecule:
def __init__(self, name):
# …
self.name = name
and we create a corresponding object via:
molecule = Molecule('myMoleculeName')
then molecule.__dict__ has an entry with key ‘name’ and value ‘myMoleculeName’.
When Python needs to access an attribute for an object it first checks in the object
__dict__ for a key equal to the attribute name, and if that does not exist it then checks in
the associated class __dict__. This can be used to set a default value using a class attribute
that can then optionally be overridden by an object attribute of the same name. Class
attributes take up less memory than an equivalent object attribute because the latter has
space allocated in the object __dict__ for every single object instance of the class.
Python’s inbuilt dir() function, which lists available attributes for a given object or
class, is related to the __dict__ attribute. Acting on a class it gives a list of the keys in the
class __dict__ and acting on an object it returns a merger of the keys for the class __dict__
and for the object __dict__:
dir(Molecule)
# list that includes ['__init__', 'getName', 'getCapitalisedName']
Although it is not a common practice, a class attribute or object attribute (including a
function) can be removed completely using a del statement. Naturally, class attributes
must use the del on the class and object attributes use the del on an object:
del AminoAcid.massDict # removes massDict from class
del molecule.name # removes name from molecule
del aminoAcid.massDict # AttributeError exception
del Molecule.name # AttributeError exception
In effect, the del operation is working on the corresponding __dict__:
del molecule.name # same as: del molecule.__dict__['name']