🏘️ Classes¶
1. Defining a Class¶
In Python, a class is defined using the class
keyword. A class can be thought of as a blueprint for creating objects with a particular set of attributes and methods.
class MyClass:
x = 5
2. Creating an Object¶
Once a class is defined, you can create an instance of the class, also known as an object.
p1 = MyClass()
print(p1.x) # prints: 5
5
3. The __init__
Method¶
The __init__
method is a special method that's called when an object is created. You can use it to set the initial state of the object.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person("Alice", 25)
print(p1.name) # prints: Alice
print(p1.age) # prints: 25
Alice 25
4. Object Methods¶
Objects can also contain methods. Methods in objects are functions that belong to the object.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hello, I'm a person!")
p1 = Person("Alice", 25)
p1.greet() # prints: Hello, I'm a person!
Hello, I'm a person!
5. The self
Parameter¶
The self
parameter is a reference to the current instance of the class, and is used to access variables and methods that belong to the class. Here's an example:
class Car:
def __init__(self, color, brand):
self.color = color
self.brand = brand
def display(self):
print("This is a", self.color, self.brand)
car1 = Car("red", "Toyota")
car1.display() # prints: This is a red Toyota
This is a red Toyota
In this code, self
is used in the __init__
method to create the color
and brand
attributes, and we use self
again in the display
method to access these attributes.
The self
parameter doesn't have to be named self
. You can call it whatever you want, but it's a convention to name it self
.
It's important to note that while self
is used in the method definitions, you do not provide it when you call the methods. Python automatically passes it for you. So when we call car1.display()
, we're not providing any arguments, but self
gets automatically associated with car1
.
6. The __str__
Method¶
You can define the __str__
method in your class to specify what should be printed when an object of the class is printed.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
p1 = Person("Alice", 25)
print(p1) # prints: Person(name=Alice, age=25)
Person(name=Alice, age=25)
7. Static Methods¶
Static methods in Python are extremely similar to normal functions except that they are part of a class. They can't modify the class state or the state of its instances. They are utility type methods that take some parameters and work upon those parameters.
Here's an example:
class Math:
@staticmethod
def add(x, y):
return x + y
print(Math.add(5, 3)) # prints: 8
8
In this example, add
is a static method that takes two numbers and returns their sum. Note the @staticmethod
decorator that's used to declare a static method.
8. Class Methods¶
While static methods are more or less detached from the class they are in, class methods are bound to the class, not its instance. They can't modify instance state (like normal methods can), but they can modify class state (which gets reflected in all instances of the class).
Class methods take a first parameter that refers to the class, conventionally named cls
.
class Person:
count = 0 # This is a class variable
def __init__(self, name):
self.name = name # This is an instance variable
Person.count += 1
@classmethod
def show_count(cls):
print(f"There are {cls.count} people.")
p1 = Person("Alice")
p2 = Person("Bob")
Person.show_count() # prints: There are 2 people.
There are 2 people.
9. Properties¶
Python provides a property decorator which gives the developers the opportunity to get the benefits of both, by providing a way to define methods that can be accessed like attributes. This allows Python developers to implement getters and setters.
class Person:
def __init__(self, name):
self._name = name # _name is private now
@property
def name(self):
print('Getting name')
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError("'name' must be a string.")
print('Setting name to', value)
self._name = value
@name.deleter
def name(self):
print('Deleting name')
del self._name
p = Person('Adam')
print(p.name) # prints: Getting name \n Adam
p.name = 'John' # prints: Setting name to John
print(p.name) # prints: Getting name \n John
del p.name # prints: Deleting name before deleting the attribute
Getting name Adam Setting name to John Getting name John Deleting name
In the code above, name
is a property object which provides interface to the private variable _name
. The @property
decorator is used to convert the name()
method into a getter for a read-only attribute. The @name.setter
and @name.deleter
decorators are used to define setter and deleter for name
property.