Setting Attributes on Objects in Python: Understanding the Restrictions
In Python, it is possible to set attributes on instances of classes inherited from the object class, but not directly on instances of the object class itself. This distinction raises the question: why are vanilla objects prohibited from having attributes assigned to them?
The Absence of a Dictionary in Object Instances
To support arbitrary attribute assignment, objects require a dict attribute, which serves as a dictionary where attributes can be stored. Instances of the object class, however, do not possess such a dict__. Creating a __dict for every object in Python would impose a significant memory overhead, since it would need to be present for all objects, even those that do not utilize attributes.
This can be demonstrated using the pympler project. Size measurements reveal that a dictionary (an object that can hold attributes) consumes 144 bytes, while an integer (an object without attributes) requires only 16 bytes. By introducing a __dict__, the memory footprint of even simple objects would grow considerably.
Inheritance and Attribute Assignment
When creating a class that inherits from the object class, the situation changes. The dict attribute is added to each instance of the new class, allowing it to have arbitrary attributes. However, this flexibility comes at a storage cost.
For example, creating a class called dint that inherits from int results in instances that occupy 184 bytes, significantly higher than the 16 bytes of a regular integer. This difference is due to the additional dict attribute.
The slots Alternative
In scenarios where instances only require a small number of specific attributes, Python provides the slots special attribute. By defining slots as a sequence of strings containing attribute names, classes can restrict the set of attributes that instances can possess. This mechanism prevents the creation of a __dict__, saving memory.
For instance, creating a class called fint that inherits from int and defines a single attribute slot called "foobar" reduces the memory footprint of instances to 80 bytes. This is still larger than an integer but significantly less than a class with a __dict__.
Conclusion
In summary, vanilla objects in Python cannot have attributes assigned to them because they do not possess a dict attribute. This is primarily done to conserve memory since a dict would be required for every object, regardless of whether it requires attributes. However, inherited classes can have attributes by including a dict and the slots mechanism provides an efficient alternative when a limited number of specific attributes are required.
The above is the detailed content of Why can't you assign attributes to vanilla objects in Python?. For more information, please follow other related articles on the PHP Chinese website!