python dunder methods

Robert 140 Published: 12/03/2024

python dunder methods

Here's a detailed explanation of Python's "dunder" (double underscore) methods:

In Python, special methods that are surrounded by double underscores (__) are called "dunder" methods. These methods have special meanings and are used to override default behaviors or provide additional functionality. Here are some common dunder methods in Python:

__init__: The constructor method, which is called when an object is created. It sets the initial state of the object.

Example:

class Person:

def init(self, name):

self.name = name

p = Person("John")

print(p.name) # Output: John

__str__ and __repr__: These methods return a string representation of an object. The difference between the two is that __str__ returns a human-readable string, while __repr__ returns a more detailed, programmer-friendly string.

Example:

class Person:

def init(self, name):

self.name = name

def str(self):

return f"{self.name}"

def repr(self):

return f"Person('{self.name}')"

p = Person("John")

print(str(p)) # Output: John

print(repr(p)) # Output: Person('John')

__eq__, __ne__, __lt__, __gt__, __le__, and __ge__: These methods are used to compare two objects for equality, inequality, less than, greater than, less than or equal to, and greater than or equal to.

Example:

class Person:

def init(self, name):

self.name = name

def eq(self, other):

return self.name == other.name

def ne(self, other):

return not self.eq(other)

p1 = Person("John")

p2 = Person("John")

print(p1 == p2) # Output: True

print(p1 != p2) # Output: False

__add__, __sub__, __mul__, __div__, etc.: These methods are used to override the behavior of arithmetic operators (+, -, *, /) when used with instances of your class.

Example:

class Vector:

def init(self, x, y):

self.x = x

self.y = y

def add(self, other):

return Vector(self.x + other.x, self.y + other.y)

v1 = Vector(2, 3)

v2 = Vector(4, 5)

print(v1 + v2) # Output: (6, 8)

__getitem__ and __setitem__: These methods are used to implement indexing on your class.

Example:

class Person:

def init(self):

self.data = {}

def getitem(self, key):

return self.data[key]

def setitem(self, key, value):

self.data[key] = value

p = Person()

p["name"] = "John"

print(p["name"]) # Output: John

__len__: This method returns the length of an object.

Example:

class List:

def init(self, items):

self.items = items

def len(self):

return len(self.items)

my_list = List(["a", "b", "c"])

print(len(my_list)) # Output: 3

__contains__: This method checks if an object is contained in another.

Example:

class Set:

def init(self, items):

self.items = set(items)

def contains(self, item):

return item in self.items

my_set = Set({"a", "b", "c"})

print("a" in my_set) # Output: True

print("d" in my_set) # Output: False

These are just a few examples of the many special methods you can define in Python. By using dunder methods, you can create custom behaviors for your classes and make them more flexible and powerful.

What is the difference between inheritance and metaclass in Python?

In Python, both inheritance and metaclasses are advanced concepts used to customize and extend the behavior of classes. While they share some similarities, they serve distinct purposes.

Inheritance

Inheritance is a mechanism that allows one class (the subclass or child) to inherit attributes and methods from another class (the superclass or parent). The subclass inherits all the properties and behavior of its superclass, and can also add new methods or override existing ones. This enables code reuse and facilitates the creation of hierarchies of classes that share common characteristics.

When a class inherits from another, it creates a "is-a" relationship between them. For example, a Car is a type of Vehicle, so we could define a Car class as a subclass of Vehicle. The Car class would inherit all the attributes and methods defined in Vehicle, such as color, speed, and accelerate(), and can also add its own unique characteristics.

Metaclasses

A metaclass is a class that creates classes. Yes, you read that correctly – a class that creates classes! When you define a class with a specific metaclass, the metaclass is responsible for creating the class itself, rather than Python's built-in type object doing it. This allows you to customize the class creation process and inject your own logic into the class definition.

In other words, a metaclass is a class that defines how classes are defined. When you define a class with a custom metaclass, you're effectively saying, "Hey, Python, when someone tries to create a class using this syntax, please use my metaclass to generate it."

Here's an analogy: think of inheritance as inheriting a set of instructions on how to build a car, whereas metaclasses are the blueprints for building the very car itself. Inheritance is about creating a new instance of an existing class, while metaclasses are about defining the overall architecture of classes.

Key differences

Purpose: Inheritance is used to create relationships between classes (e.g., "a Car is a Vehicle"), whereas metaclasses are used to customize the process of creating classes themselves. Scope: Inheritance affects the instances of a class, while metaclasses affect the class definition itself. Behavior: Inheritance allows you to override or extend methods and attributes, whereas metaclasses allow you to inject custom logic into the class creation process.

In summary, inheritance is about creating relationships between classes, while metaclasses are about defining how those classes are created. Both concepts can be powerful tools in your Python programming toolkit, but they serve distinct purposes.