在 Python 中,魔法函数(Magic Methods)也称为双下划线方法(Dunder Methods),是指那些名字以双下划线开头和结尾的特殊方法。 这些方法可以让您的自定义类实现一些特定的行为,从而与 Python 的内置类型和操作进行交互。
例如,`__init__` 方法用于对象的初始化,`__str__` 方法用于定义对象的字符串表示形式,`__add__` 方法用于实现对象的加法操作等。
以下是一些常见魔法函数的示例及其作用:
1. `__init__`:在创建对象时自动调用,用于初始化对象的属性。
class MyClass:
def __init__(self, value):
self.value = value
例子:创建“Student”类,对应逻辑关系:
Student→self→{name,age,grade}(三个逻辑分支)
# 创建学生对象
student1 = Student("Alice", 12, 6)
#类的实例化
class Student:
def __init__(self, name, age, grade):
self.name = name
self.age = age
self.grade = grade
# 创建学生对象
student1 = Student("Alice", 12, 6)
print(student1.name)
print(student1.age)
print(student1.grade)
2. `__str__`:定义对象的字符串表示,当使用 `str()` 函数或在打印对象时调用。
class MyClass:
def __str__(self):
return f"MyClass with value: {self.value}"
例子:
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return f"My value is {self.value}"
my_object = MyClass(42)
print(str(my_object))
在这段代码中,`42` 这个值的传递关系如下: 当创建对象 `my_object = MyClass(42)` 时,`42` 作为参数被传递给了 `MyClass` 类的 `__init__` 方法。 在 `__init__` 方法内部,`42` 被赋值给了对象的 `self.value` 属性,使得该对象具有了 `value` 属性且其值为 `42` 。 当执行 `str(my_object)` 或 `print(my_object)` 时,会调用 `__str__` 方法,在 `__str__` 方法中通过 `self.value` 访问到了之前存储的 `42` 值,并将其用于生成返回的字符串 `My value is 42` 。 简单来说,`42` 从创建对象时作为参数传入,被存储在对象的属性中,然后在需要时被 `__str__` 方法获取并使用。
3. `__add__`:实现对象的加法操作。
class MyNumber:
def __init__(self, num):
self.num = num
def __add__(self, other):
return MyNumber(self.num + other.num)
例子:
class MyNumber:
def __init__(self, num):
self.num = num
def __add__(self, other):
return MyNumber(self.num + other.num)
num1 = MyNumber(5)
num2 = MyNumber(3)
result = num1 + num2
print(result.num)
4. `__len__`:用于 `len()` 函数获取对象的长度。
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
例子:
class MyList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = MyList([1, 2, 3, 4, 5])
print(len(my_list))
通过合理地定义魔法函数,可以使自定义类的行为更加自然和符合 Python 的习惯用法。
以下是一些常见的 Python 魔法函数及它们的作用:
1. `__init__(self,...)`:对象初始化函数,在创建对象时调用,用于进行对象的初始化操作。
2. `__str__(self)`:直接打印对象的实现方法,被`print`函数调用,返回对象的字符串表示。
3. `__new__(cls, *args, **kwargs)`:在对象实例化时首先被调用,用于创建并返回实例对象。
4. `__unicode__(self)`:在一个对象上调用`unicode()`时被调用,常用于 Django 模型中处理字符串。
5. `__call__(self, *args, **kwargs)`:允许一个类的实例像函数一样被调用。
6. `__len__(self)`:定义当被`len()`调用时的行为,需要返回一个整数,表示对象的长度。
7. `__repr__(self)`:用于将值转化为供解释器读取的形式,如果对象没有适于人阅读的解释形式,`str()`会返回与`repr()`相同的内容。
8. `__setattr__(self, name, value)`:可以设置对象的属性。
9. `__getattr__(self, name)`:获取对象属性,在属性没有找到时被调用。
10. `__getattribute__(self, name)`:无条件地获取对象属性,可用于做一些控制,但定义后`__getattr__`不再自动调用,除非显式调用。
11. `__delattr__(self, name)`:用于删除对象的属性。
12. `__setitem__(self, key, value)`:实现该函数后,可以以下标的方式给对象赋值。
13. `__getitem__(self, key)`:可以使对象支持以下标的方式获取值。
14. `__delitem__(self, key)`:支持以下标方式删除对象数据。
15. `__iter__(self)`:只要定义了该方法,对象就可以使用迭代器访问,意味着可以迭代自定义的对象。
16. `__del__(self)`:析构器或回收器,在对象引用数降到 0 时执行,但执行时间可能不确定,一般不推荐使用,可用于实现一些非紧急但必须要做的事。
17. `__eq__(self, other)`:定义等于号的行为,用于判断两个对象是否相等。
18. `__lt__(self, other)`:定义小于号的行为,用于判断一个对象是否小于另一个对象。
19. `__gt__(self, other)`:定义大于号的行为,用于判断一个对象是否大于另一个对象。
20. `__add__(self, other)`:定义加法操作的行为。
21. `__sub__(self, other)`:定义减法操作的行为。
22. `__mul__(self, other)`:定义乘法操作的行为。
23. `__truediv__(self, other)`:定义真除法操作的行为。
24. `__floordiv__(self, other)`:定义整数除法操作的行为。
25. `__mod__(self, other)`:定义取模算法的行为。
26. `__pow__(self, other, modulo)`:定义当被`power()`调用或 `**` 运算时的行为。
27. `__radd__(self, other)`等(反运算魔法方法):当左操作数不支持相应的操作时被调用,例如`__radd__`在执行`other + self`时被调用。
28. `__iadd__(self, other)`等(增量赋值运算魔法方法):定义相应的增量赋值运算行为,如`__iadd__`定义`+=`的行为。
29. `__neg__(self)`:定义正号的行为。
30. `__pos__(self)`:定义负号的行为。
31. `__abs__(self)`:定义当被`abs()`调用时的行为。
32. `__invert__(self)`:定义按位求反的行为。
33. `__complex__(self)`:定义当被`complex()`调用时的行为,需要返回恰当的值。
34. `__int__(self)`:定义当被`int()`调用时的行为,需要返回恰当的值。
35. `__float__(self)`:定义当被`float()`调用时的行为,需要返回恰当的值。
36. `__round__(self, n)`:定义当被`round()`调用时的行为,需要返回恰当的值。
37. `__index__(self)`:当对象应用在切片表达式中时,实现强制转换;如果定义了该方法,则也需要定义`__int__`且返回相同的值。
魔法函数可以让自定义类具有更丰富的行为,类似于 Python 内置类型的操作方式,从而使代码更加简洁、易读和可维护。它们的具体使用方式和效果取决于具体的需求和上下文。在实际编程中,根据需要选择合适的魔法函数来定制类的行为。