Python 自带魔法方法重点解析

Python 自带魔法方法掌握了就事半功倍

Python 的魔法方法是以双下划线开头和结尾的特殊方法。它们允许我们在自定义类中实现类似内置类型的行为,如支持算术运算、索引、迭代等。以下是按功能分类的全面总结,每个分类都有代码案例和详细解释。

1. 对象初始化与表示

1.1 __init____new__

  • 作用: 初始化对象和控制对象的创建。
1
2
3
4
5
6
7
8
9
10
11
class MyClass:
def __new__(cls, *args, **kwargs):
print("__new__ is called")
instance = super().__new__(cls)
return instance

def __init__(self, value):
print("__init__ is called")
self.value = value

obj = MyClass(42)
  • 解释:

1.__new__:

控制对象的创建过程。
必须返回一个实例对象。
通常用在需要定制实例化流程的场景,比如实现单例模式。

2.__init__:

初始化对象的属性。
接受实例创建后的数据,并设置初始状态。

1.2 __repr__ __str__

  • 作用: 定义对象的字符串表示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

def __repr__(self):
return f"Point({self.x}, {self.y})"

def __str__(self):
return f"Point at ({self.x}, {self.y})"

p = Point(1, 2)
print(repr(p)) # 输出:Point(1, 2)
print(str(p)) # 输出:Point at (1, 2)
  • 解释:

1.__repr__:

返回开发者友好的表示,通常用于调试。
通常要求输出的字符串能用 eval() 重建该对象。

2.__str__:

返回用户友好的字符串,适合显示给最终用户。

2.算术运算

2.1 算数运算符 __add__ __sub__

  • 作用: 支持自定义类的加、减、乘等运算。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Number:
    def __init__(self, value):
    self.value = value

    def __add__(self, other):
    return Number(self.value + other.value)

    def __sub__(self, other):
    return Number(self.value - other.value)

    def __repr__(self):
    return f"Number({self.value})"

    n1 = Number(10)
    n2 = Number(20)
    print(n1 + n2) # 输出:Number(30)
    print(n1 - n2) # 输出:Number(-10)
  • 解释:

1.__add__:

定义加法操作 +。
接受另一个对象作为参数,并返回新的结果。

2.__sub__:

定义减法操作 -。
类似的魔法方法还有:
__mul__: 定义乘法 *。
__truediv__: 定义除法 /。
__floordiv__: 定义整除 //。
__mod__: 定义取模 %。
__pow__: 定义幂运算 **

2.2 反向运算 _radd_

  • 作用: 当左操作数不支持运算时调用。
1
2
3
4
5
6
7
8
9
10
11
12
class Number:
def __init__(self, value):
self.value = value

def __radd__(self, other):
return Number(self.value + other)

def __repr__(self):
return f"Number({self.value})"

n = Number(10)
print(5 + n) # 输出:Number(15)
  • 解释:

1.__radd__:

定义反向加法。
在常规 __add__ 不被调用时(如左操作数是非自定义类型)使用。

2.类似的反向运算符还有:
__rsub__: 反向减法。
__rmul__: 反向乘法。
__rtruediv__: 反向除法。

3.容器操作

3.1 索引访问 __getitem__ __setitem__以及__delitem__

  • 作用: 支持对象的索引操作。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class CustomList:
    def __init__(self, items):
    self.items = items

    def __getitem__(self, index):
    return self.items[index]

    def __setitem__(self, index, value):
    self.items[index] = value

    def __delitem__(self, index):
    del self.items[index]

    cl = CustomList([10, 20, 30])
    print(cl[1]) # 输出:20
    cl[1] = 99
    print(cl[1]) # 输出:99
    del cl[1]
    print(cl.items) # 输出:[10, 30]
  • 解释:

1.__getitem__:

定义对象的索引读取。
允许使用 obj[index] 的形式访问。

2.__setitem__:

定义索引赋值。
支持 obj[index] = value。

3.__delitem__:

定义索引删除。
支持 del obj[index]。

3.2 容器长度与成员检查 __len__ __contains__

  • 作用: 支持 len() 和 in 操作。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Bag:
    def __init__(self, items):
    self.items = items

    def __len__(self):
    return len(self.items)

    def __contains__(self, item):
    return item in self.items

    bag = Bag(["apple", "banana", "cherry"])
    print(len(bag)) # 输出:3
    print("apple" in bag) # 输出:True

  • 解释:

1.___len__:

定义对象的长度。
支持 len(obj)。

2.__contains__:

定义成员关系操作。
支持 item in obj。

4.迭代器协议

4.1 迭代支持 __iter__ __next__

  • 作用: 自定义对象支持迭代。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class MyRange:
    def __init__(self, start, end):
    self.current = start
    self.end = end

    def __iter__(self):
    return self

    def __next__(self):
    if self.current >= self.end:
    raise StopIteration
    self.current += 1
    return self.current - 1

    for i in MyRange(1, 5):
    print(i) # 输出:1 2 3 4

  • 解释:

1.__iter__:

返回迭代器本身。

2.__next__:

定义每次迭代返回的值。
当没有值可返回时,抛出 StopIteration。

5.上下文管理

5.1 上下文管理协议 __enter__ __exit__

  • 作用: 支持 with 语句。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class File:
    def __init__(self, filename, mode):
    self.filename = filename
    self.mode = mode

    def __enter__(self):
    self.file = open(self.filename, self.mode)
    return self.file

    def __exit__(self, exc_type, exc_value, traceback):
    self.file.close()

    with File("example.txt", "w") as f:
    f.write("Hello, World!")

  • 解释:

1.__enter__:

在进入上下文时执行。
返回资源对象。

2.__exit__:

在离开上下文时执行。
负责清理资源。

6.其他常用魔法方法

6.1 __call__

  • 作用: 使对象像函数一样调用。
1
2
3
4
5
6
7
class Greeter:
def __call__(self, name):
return f"Hello, {name}!"

greet = Greeter()
print(greet("Alice")) # 输出:Hello, Alice!

  • 解释:

1.__call__:
运行的时候可以直接调用函数

6.2 __del__

  • 作用: 定义对象销毁时的行为。
1
2
3
4
5
6
7
class Resource:
def __del__(self):
print("Cleaning up resources!")

res = Resource()
del res # 输出:Cleaning up resources!

  • 解释:

1.__del__:
运行的时候可以直接在销毁对象执行的行为

6.3 比较操作符 __eq_ __lt__

  • 作用: 支持比较运算符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Number:
def __init__(self, value):
self.value = value

def __eq__(self, other):
return self.value == other.value

def __lt__(self, other):
return self.value < other.value

n1 = Number(10)
n2 = Number(20)
print(n1 == n2) # 输出:False
print(n1 < n2) # 输出:True

  • 解释:

1.__eq__:
定义 ==。

2.__lt__:
定义 <。

3.还有类似的:
__le__ (<=)
__gt__ (>)
__ge__ (>=)

总结

上面的这些魔法方法只是python中用的比较多的一部分,还有很多,有时候在编程的时候使用这些高效的魔法方法也是很不错的选择!


Python 自带魔法方法重点解析
https://dreamshao.github.io/2024/12/12/python魔法方法/
作者
Yun Shao
发布于
2024年12月12日
许可协议