Lately I've been having so much fun learning Python. Compared to the C language Python is way easier to learn and this comes as a result of Guido Van Rossum’s concept of creating a programming language that’s “first-class everything” What it means that all the functions, classes, modules, methods and data types all have equal status.
And pretty much that’s why everything in Python is almost a class. What is a class you might ask? a class is a indented block of statements that contains attributes, properties, methods… an be used just like the built-in data types like dict int and str. In this blog post however we’re mainly going to focus on attributes.
What’s a class attribute?
Attributes define a feature or a property of a class they can be methods or variables that are function s that’s been defined inside the class taking example : <className>.<methodName(arguments>.
- Protected by “__”, private attributes can only be modified and used inside the class.
- Protected by “_”, protected attributes could be used outside of the class, but only under certain conditions.
- Finally public attributes could be used and modified by everybody, inside and outside of the class.
let’s go back to our main question, What exactly is a class attribute?
Class attributes differ from instance attributes instead of being owned by one specific instance of the class only and not shared between instances Class attributes are variables of a class shared between all of its instances .
Example of a class attribute:
class A:
a = "I am a class attribute!"
x = A()
y = A()
x.a
What’s an instance attribute and how to create them?
Instance attributes are unique to each object and owned by the specific instances of a class, (an instance is another name for an object). We can change either attribute of either object, without affecting any other objects we’ve created.
class A:
a = "I am a class attribute!"
x = A()
y = A()
x.a = "This creates a new instance attribute for x!"
Creating Classes and Instance Pythonic and non-Pythonic
- the non-Pythonic way:
class Square:
def __init__(self, size=0):
if not isinstance(size, int):
raise TypeError("size must be an integer")
if size < 0:
raise ValueError("size must be >= 0")
self.__size = size * size def area(self):
return self.__sizet__width()
- the Pythonic way:
class Square:
def __init__(self, size=0):
self.size = size @property
def size(self):
return self.__size @size.setter
def size(self, value):
if not isinstance(value, int):
raise TypeError("size must be an integer")
if value < 0:
raise ValueError("size must be >= 0")
self.__size = value def area(self):
return self.__size * self.__size
Differences Between Class and Instance Attributes:
The difference between class and instance attributes is that class attributes are shareable by all instances. Instances that share the exact value are affected by changing the value of a class attribute on the other hand and as i mentioned before the attribute of an instance on the other hand is unique to that instance.
Advantages of class attributes:
The ability to storing relevant data to all the instances For example, having a counter class attribute that increments every time we create a new instance and decrements every time we delete an instance. This way we we’ll be able to always keep track of the instances having the same class.
Disadvantages of class attributes:
- the behavior can be unexpected when creating an instance with a different class value than the class attribute value itself.
- the fact It’s not possible to have two instances with different values.
Advantages of instance attributes:
- Thanks to properties they are easy to set and get They’re also specific to an object .
- they‘re discarded once the instance that they associates with is being deleted which makes things clearer.
Disadvantages of instance attributes:
- it’s hard to keep track of the values in between instances
- as much as it is an advantage losing their values on deletion is a disadvantage when you want to keep history of values.
How Does Python Deal with Instance and Class Attributes Using the Dictionary?
Python’s object attributes and class attributes are being stored in separate dictionaries. which they use to store their attributes and their corresponding values. All instances have a __dict__ dictionary for example :
person_1 = Person('Camila')
person_1.class_attr = "This is a changed class attribute"
person_2 = Person('Harry')
print(person_1.__dict__)
print(person_2.__dict__)
print(Person.__dict__)
The output is :
{'_Person__name': 'Camila', 'class_attr': 'This is a changed class attribute'}
{'_Person__name': 'Harry'}
{'__doc__': None, 'class_attr': 'I am a class attribute', '__init__': <function Person.__init__ at 0x7f687cb7b950>, '__module__': '__main__', 'name': <property object at 0x7f687cadb6d8>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__dict__': <attribute '__dict__' of 'Person' objects>}
The __dict__ will only display instance attributes. a dictionary with attributes will be printed when applying __dict__ on the Person class because even though Person is a class, it has attributes that can be listed because it’s technically an object . Notice the ‘class_attr’: ‘I am a class attribute’, that is a class attribute, and the name attribute that doesn’t have a value because its value is given in every instantiation of the class.
Conclusion
classes are powerful and very used when it comes to Object-Oriented Programming . Choosing the class or instance attributes is up to the kind of class we want or need to create however we have to make sure we know and understand them both very well before actually using them