Class and instance attributes Python
- An instance attribute is a Python variable belonging to one, and only one, object. This variable is only accessible in the scope of this object and it is defined inside the constructor function,
__init__(self,..)
of the class. - A class attribute is a Python variable that belongs to a class rather than a particular object. It is shared between all the objects of this class and it is defined outside the constructor function,
__init__(self,...)
, of the class.
The below ExampleClass
is a basic Python class with two attributes: class_attr
and instance_attr:
class ExampleClass(object):class_attr = 0def __init__(self, instance_attr):self.instance_attr = instance_attr
What’s a class attribute
Instance attributes are owned by the specific instances of a class. This means for two different instances the instance attributes are usually different. You should by now be familiar with this concept which we introduced the previous chapter.
We can also define attributes at the class level. Class attributes are attributes which are owned by the class itself. They will be shared by all the instances of the class. Therefore they have the same value for every instance. We define class attributes outside of all the methods, usually they are placed at the top, right below the class header.
What’s an instance attribute
An instance attribute is a Python variable belonging to only one object. It is only accessible in the scope of the object and it is defined inside the constructor function of a class. For example, __init__(self,..).
What are all the ways to create them and what is the Pythonic way of doing it
Create class attribute outside the class declaration:
What are the differences between class and instance attributes
Both class and instance attribute differences can be explained using __dict__
attribute and the term namespace. A namespace is a mapping from names to objects, with the property that there is zero relation between names in different namespaces. They’re usually implemented as Python dictionaries. Python classes and instances of classes each have their own distinct namespaces. When you try to access an attribute, python will loop for that attribute inside local namespace:
>>> object = NewClass()
>>> object.__dict__
{}
>>> object.attribute
'This is an attribute of a class'
What are the advantages and drawbacks of each of them
Advantages of class attributes:
- Classes provide an easy way of keeping the data members and methods together in one place which helps in keeping the program more organized.
- Using classes also provides another functionality of this object-oriented programming paradigm, that is, inheritance.
- Classes also help in overriding any standard operator.
- Using classes provides the ability to reuse the code which makes the program more efficient.
- Grouping related functions and keeping them in one place (inside a class) provides a clean structure to the code which increases the readability of the program.
Disadvantages of class attributes:
- Class attributes can become messy when instance attributes with the same names are created, meaning that its behavior can become unexpected.
Advantages of instance attributes:
- They are specific to an object
- They can coexist with class variables while having the same name
Disadvantages of instance attributes:
- we can’t accessed by another instance
- if instance is deleted, all attributes are gone.
How does Python deal with the object and class attributes using the __dict__
In Python, all instance variables are stored as a regular dictionary. When working with attributes, you just changing a dictionary.
We can access instance dictionary by calling __dict__
dunder (magic) method:
>>> car.__dict__
{'manufacturer': 'Toyota', 'model_name': 'Corolla'}
As I said earlier, class attributes are owned by a class itself (i.e., by its definition). As it turns out, classes are using a dictionary too
>>> Vehicle.__dict__
mappingproxy({'__module__': 'main', 'kind': 'car',
'lst': [1], '__init__': <function Vehicle.__init__ at 0x109228488>,
'name': <property object at 0x1091f8098>,
'__repr__': <function Vehicle.__repr__ at 0x109228598>,
'from_dict': <staticmethod object at 0x1091f6d30>,
'__dict__': <attribute '__dict__' of 'Vehicle' objects>,
'__weakref__': <attribute '__weakref__' of 'Vehicle' objects>, '__doc__': None})
Class dictionary can also be accessed from an instance, using __class__
dunder method (car.__class__.__dict__
).
Dictionaries of classes are protected by mappingproxy
. The proxy checks that all attribute names are strings, which helps to speed-up attribute lookups. As a downside, it makes dictionary read-only.
Because all methods belong to a class, they are also stored in this dictionary.