Attributes
What are attributes? Is it an object inside of another object? Or is it a method, property, etc?
Semantically, in English, properties and attributes are the same thing. However, in Python, we typically mean property
to mean an attribute that has its access (lookup, assignment, and deletion) programmatically managed.
Attributes provide information about objects. For example, a circle may be defined by its radius. Thus we might say the defining attribute of a circle is its radius attribute. We could model such an object like this:
class Circle(object):
def __init__(self, radius):
self.radius = radius
However, other information we might like to know about such a circle could be its diameter, circumference, or its area. These are also attributes of a circle. However, since we can calculate them from the radius, we might choose to use Python's property
decorator:
@property
def diameter(self):
return self.radius * 2
A property defined in this way would be read-only. We could do similarly for circumference and area (but the implementation is left as an exercise for the reader). We use both the radius attribute and the diameter property in the same way:
>>> c = Circle(5)
>>> c.radius
5
>>> c.diameter
10
But we will find that if we try to change the diameter, we cannot directly, we would have to change the radius instead.
>>> c.diameter = 20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> c.radius = 10
>>> c.diameter
20
Everything is an object in Python
Is it an object inside of another object?
Well, in Python everything is an object, so all data members of an object are objects too. In objects that don't declare a __slots__
, the data members are stored in a dictionary (another object) on the __dict__
attribute name.
If objects declare __slots__
the data members are stored in a kind of mutable tuple, but there are lots of caveats for __slots__
.
Methods
Or is it a method, property, etc?
A method is actually more of an attribute of the class definition (it is in the class's __dict__
, not the instance's), but it is bound to the instance on a dotted lookup from an instance (for more on this, see descriptors - an advanced topic). Semantically, it's also an attribute of the instance though.
You can read more about methods here.
Attributes and dir
When you do dir(), what's the differences between the slots and the rest of the attributes?
dir
just tells you (most of) the names that are available on the object.
>>> dir(c)
['__class__', '__delattr__', ... 'diameter', 'radius'] # some removed
So that includes functions and properties which are actually attributes of the class of the object.
If you want to know what are the actual data members in an object, use the vars builtin:
>>> vars(c)
{'radius': 5}
And by this inspection we see that the data stored for this circle is not both radius and diameter, but only radius.
(A unique counter-example for dir
: If you do dir(AClass)
it won't tell you about the AClass.mro()
though, which is mostly a CPython implementation detail.)