文章目录
- 1.什么是魔法函数?
- 2.魔法函数的特点
- 3.魔法函数有什么作用?
- 4.常见魔法函数
- 1.__init__(self[, args...]):对象初始化函数,在创建对象时调用。
- 2.__str__(self):返回对象的字符串表示。
- 3.__len__(self):返回对象的长度。
- 4.__getitem__(self, key):获取对象的指定元素。
- 5.__setitem__(self, key, value):设置对象的指定元素。
- 6.__delitem__(self, key):删除对象的指定元素。
- 7.__contains__(self, item):判断对象是否包含指定元素。
- 8.__iter__(self):返回迭代器对象。
- 9.__next__(self):返回迭代器的下一个元素。
- 10.__eq__(self, other):判断两个对象是否相等。
- 11.__lt__(self, other):判断一个对象是否小于另一个对象。
- 12.__gt__(self, other):判断一个对象是否大于另一个对象。
- 13.__add__(self, other):定义对象的加法操作。
- 14.__sub__(self, other):定义对象的减法操作。
- 15.__mul__(self, other):定义对象的乘法操作。
- 16.__call__(self[, args...]):使对象可调用。
- 17.__enter__(self) 和 __exit__(self, exc_type, exc_value, traceback):定义上下文管理器。
- 18.__getattr__(self, name):在访问不存在的属性时调用。
- 19.__setattr__(self, name, value):在设置属性值时调用。
- 20.__delattr__(self, name):在删除属性时调用。

1.什么是魔法函数?
- 魔法函数是Python中定义的,以__开头,结尾,形如__fun()的函数,一般使用已经定义好了的即可。
- 使用这样一些函数,可以让我们自定义的类有更加强大的特性。
- 魔法函数一般是隐式调用的,不需要我们显示调用。(即python解释器帮我们调用实现)
2.魔法函数的特点
- 以双下划线开头和结尾(如__init__)
- 由Python解释器自动调用,通常不直接调用
- 为类提供特殊功能,使其行为更像内置类型
魔法函数的优缺点
优点:
增强代码的可读性和可维护性。
提高代码的灵活性和功能。
与Python语言深度集成。
缺点:
滥用可能导致代码复杂性和难以理解。
可能引入性能开销,特别是在频繁调用时。
不当使用可能导致调试困难。
3.魔法函数有什么作用?
- 实现特殊操作:用于对象的初始化(init)、销毁(del)、属性访问(getattr、setattr、delattr)等。
- 运算符重载:允许自定义类重载标准运算符,如加法(add)、减法(sub)、乘法(mul)等,使对象可以像内置类型一样参与运算。
- 支持内置函数和协议:通过实现特定方法,如__len__、iter、__getitem__等,使自定义对象支持内置函数(如len()、iter())和协议(如迭代协议)。
- 增强可读性和可维护性:利用运算符重载和内置协议,使代码更简洁易懂。
- 提高代码灵活性:允许定义对象的复杂行为,增强自定义类的表现力和灵活性。
- 与Python语言深度集成:利用Python的动态特性,使自定义对象无缝融入Python生态系统。
常见的魔法函数
- init(self,…):构造函数,在创建对象时自动调用,用于初始化对象的属性。
- str(self):返回对象的字符串表示,用于print()函数或str()转换。
- repr(self):返回对象的官方字符串表示,通常用于调试,由repr()函数调用。
- len(self):定义对象的长度,用于len()函数。
- getitem(self, key):允许对象使用索引操作,如obj[key]。
- setitem(self, key, value):允许对象使用索引赋值,如obj[key] = value。
- eq(self, other):定义等号(==)的行为,用于比较两个对象是否相等。
- add(self, other):定义加号(+)的行为,用于对象的加法运算。
- iter(self) 和 next(self):使对象成为迭代器,分别返回迭代器本身和序列的下一个元素。
- call(self,…):使实例能够像函数一样被调用。
魔法函数可以为你写的类增加一些额外功能,方便使用者理解。举个简单的例子,我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类:
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
return
def __str__(self):
return self.name + ":" + str(self.age)
def __lt__(self, other):
return self.name < other.name if self.name != other.name else self.age < other.age
if __name__=="__main__":
print("\t".join([str(item) for item in sorted([People("abc", 18),
People("abe", 19), People("abe", 12), People("abc", 17)])]))
4.常见魔法函数
1.init(self[, args…]):对象初始化函数,在创建对象时调用。
class MyClass:
def __init__(self, name):
self.name = name
obj = MyClass("Alice")
2.str(self):返回对象的字符串表示。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
p = Point(3, 4)
print(p) # 输出: (3, 4)
3.len(self):返回对象的长度。
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)) # 输出: 5
4.getitem(self, key):获取对象的指定元素。
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
print(my_list[2]) # 输出: 3
5.setitem(self, key, value):设置对象的指定元素。
class MyList:
def __init__(self, items):
self.items = items
def __setitem__(self, index, value):
self.items[index] = value
my_list = MyList([1, 2, 3, 4, 5])
my_list[2] = 10
print(my_list.items) # 输出: [1, 2, 10, 4, 5]
6.delitem(self, key):删除对象的指定元素。
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
del self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
del my_list[2]
print(my_list.items) # 输出: [1, 2, 4, 5]
7.contains(self, item):判断对象是否包含指定元素。
class MyList:
def __init__(self, items):
self.items = items
def __contains__(self, item):
return item in self.items
my_list = MyList([1, 2, 3, 4, 5])
print(3 in my_list) # 输出: True
8.iter(self):返回迭代器对象。
class MyList:
def __init__(self, items):
self.items = items
def __iter__(self):
return iter(self.items)
my_list = MyList([1, 2, 3, 4, 5])
for item in my_list:
print(item) # 依次输出: 1, 2, 3, 4, 5
9.next(self):返回迭代器的下一个元素。
class MyList:
def __init__(self, items):
self.items = items
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.items):
raise StopIteration
value = self.items[self.index]
self.index += 1
return value
my_list = MyList([1, 2, 3, 4, 5])
for item in my_list:
print(item) # 依次输出: 1, 2, 3, 4, 5
10.eq(self, other):判断两个对象是否相等。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(3, 4)
p2 = Point(3, 4)
print(p1 == p2) # 输出: True
11.lt(self, other):判断一个对象是否小于另一个对象。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __lt__(self, other):
return self.x < other.x and self.y < other.y
p1 = Point(2, 3)
p2 = Point(3, 4)
print(p1 < p2) # 输出: True
12.gt(self, other):判断一个对象是否大于另一个对象。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __gt__(self, other):
return self.x > other.x and self.y > other.y
p1 = Point(3, 4)
p2 = Point(2, 3)
print(p1 > p2) # 输出: True
13.add(self, other):定义对象的加法操作。
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(1, 2)
v2 = Vector(3, 4)
result = v1 + v2
print(f"({result.x}, {result.y})") # 输出: (4, 6)
14.sub(self, other):定义对象的减法操作。
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
v1 = Vector(3, 4)
v2 = Vector(1, 2)
result = v1 - v2
print(f"({result.x}, {result.y})") # 输出: (2, 2)
15.mul(self, other):定义对象的乘法操作。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __mul__(self, factor):
return Point(self.x * factor, self.y * factor)
p = Point(2, 3)
result = p * 2
print(f"({result.x}, {result.y})") # 输出: (4, 6)
16.call(self[, args…]):使对象可调用。
class Calculator:
def __call__(self, a, b):
return a + b
calc = Calculator()
result = calc(3, 4)
print(result) # 输出: 7
17.enter(self) 和 exit(self, exc_type, exc_value, traceback):定义上下文管理器。
class FileManager:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'r')
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with FileManager("example.txt") as file:
contents = file.read()
print(contents)
18.getattr(self, name):在访问不存在的属性时调用。
class Person:
def __getattr__(self, name):
return f"Attribute '{name}' does not exist."
p = Person()
print(p.age) # 输出: Attribute 'age' does not exist.
19.setattr(self, name, value):在设置属性值时调用。
class Person:
def __setattr__(self, name, value):
print(f"Setting attribute '{name}' to '{value}'")
super().__setattr__(name, value)
p = Person()
p.name = "Alice" # 输出: Setting attribute 'name' to 'Alice'
20.delattr(self, name):在删除属性时调用。
class Person:
def __delattr__(self, name):
print(f"Deleting attribute '{name}'")
super().__delattr__(name)
p = Person()
del p.name # 输出: Deleting attribute 'name'