魔法函数指南
一、简介
魔法方法(magic methods)是 Python 中的特殊方法,其名称以双下划线开头和结尾(例如 __init__),用于在类定义中实现特定功能的功能。
Python 解释器根据特定的魔法方法来执行对象的操作。例如,当我们创建一个新的对象时,解释器自动调用对象的 __new__ 方法来分配内存,并使用对象的 __init__ 方法进行初始化。当我们使用 + 运算符将两个对象相加时,解释器自动调用对象的 __add__ 方法来实现加法操作。
魔法方法可以使开发者更加方便地控制类的行为,同时也提供了一些有用的功能,例如自定义对象的打印输出、格式化字符串、属性访问和设置、运算符重载等。
在 Python 中,魔法方法非常丰富,涵盖了各种不同的功能和用途。熟练掌握这些魔法方法,可以大幅提高代码的可读性和灵活性,并且能够更加深入地理解 Python 语言的本质。
二、 分类
根据其功能和使用场景的不同,魔法方法可以分为以下几类(由于排版问题,想看代码实例可全局搜索):
1. 对象创建和初始化类:
__new__(cls, ...):用于创建对象。__init__(self, ...):用于初始化对象。
2. 对象表示和转换:
__str__(self):定义了该类的实例被打印时的输出内容。__repr__(self):定义了该类的实例在交互模式下被调用时的输出内容。__format__(self, format_spec):定义了该类的实例被格式化时的输出形式。__bytes__(self):定义了该类的实例被转换成字节序列的方式。
3. 属性访问和设置:
__getattr__(self, name):在对象的属性未找到时被调用。__getattribute__(self, name):在对象的属性被访问时被调用。__setattr__(self, name, value):在对象的属性被设置时被调用。__delattr__(self, name):在对象的属性被删除时被调用。
4. 运算符重载:
__eq__(self, other):定义了相等操作符(==)的实现。__ne__(self, other):定义了不等于操作符(!=)的实现。__lt__(self, other):定义了小于操作符(<)的实现。__le__(self, other):定义了小于等于操作符(<=)的实现。__gt__(self, other):定义了大于操作符(>)的实现。__ge__(self, other):定义了大于等于操作符(>=)的实现。__add__(self, other):定义了加法操作符(+)的实现。__sub__(self, other):定义了减法操作符(-)的实现。__mul__(self, other):定义了乘法操作符(*)的实现。__truediv__(self, other):定义了真除法操作符(/)的实现。__floordiv__(self, other):定义了整除法操作符(//)的实现。__mod__(self, other):定义了取模操作符(%)的实现。__pow__(self, other [, modulo]):定义了幂次方操作符(**)的实现。__and__(self, other):定义了按位与操作符(&)的实现。__or__(self, other):定义了按位或操作符(|)的实现。__xor__(self, other):定义了按位异或操作符(^)的实现。__lshift__(self, other):定义了左移操作符(«)的实现。__rshift__(self, other):定义了右移操作符(»)的实现。
5. 序列和映射:
__len__(self):定义了该类的实例长度,即元素的个数。__getitem__(self, key):定义了该类的实例通过索引访问元素的方式。__setitem__(self, key, value):定义了该类的实例通过索引设置元素的方式。__delitem__(self, key):定义了该类的实例通过索引删除元素的方式。__iter__(self):定义了该类的实例可迭代的方式。__reversed__(self):定义了该类的实例反向迭代
三、 代码实例
以下是这些魔法方法的使用实例:
__new__(cls, …) 方法是创建对象时第一个被调用的方法,它用于创建并返回一个新的实例对象。我们可以通过重载这个方法,自定义对象的创建方式。
下面是一个使用 __new__ 创建单例模式的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # 输出 True
在此示例中,我们定义了一个名为 Singleton 的类,它只能创建一个实例对象。我们通过重载 __new__ 方法,创建一个 _instance 类属性,用于保存当前已经创建的实例对象。在每次创建实例对象时,我们首先检查 _instance 是否为空,如果为空则创建新的实例对象;否则返回已经存在的实例对象。
在以上示例中,我们创建了两个实例对象 s1 和 s2,但是它们实际上是同一个对象,因此输出结果为 True。这就是单例模式的应用场景之一。
__str__(self)
__str__ 方法定义了该类的实例被打印时的输出内容。我们可以通过重载这个方法,自定义对象被打印时输出的字符串。
1
2
3
4
5
6
7
8
9
10
class MyClass:
def __init__(self, name):
self.name = name
def __str__(self):
return f"MyClass: {self.name}"
obj = MyClass("foo")
print(obj) # 输出 "MyClass: foo"
在此示例中,我们定义了一个名为 MyClass 的类,它有一个属性 name 表示对象的名称。通过重载 __str__ 方法,我们定义了对象被打印时输出的字符串。
__repr__(self)
__repr__ 方法定义了该类的实例在交互模式下被调用时的输出内容。我们可以通过重载这个方法,自定义对象在交互模式下被调用时输出的字符串。
1
2
3
4
5
6
7
8
9
10
class MyClass:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"MyClass('{self.name}')"
obj = MyClass("foo")
obj # 在交互模式下输出 "MyClass('foo')"
在此示例中,我们定义了一个名为 MyClass 的类,它有一个属性 name 表示对象的名称。通过重载 __repr__ 方法,我们定义了对象在交互模式下被调用时输出的字符串。
__format__(self, format_spec)
__format__ 方法定义了该类的实例被格式化时的输出形式。我们可以通过重载这个方法,自定义对象被格式化时输出的字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyClass:
def __init__(self, value):
self.value = value
def __format__(self, format_spec):
if format_spec == "hex":
return hex (self.value)
elif format_spec == "bin":
return bin (self.value)
else:
return str (self.value)
obj = MyClass(42)
print("Value in hex: {:hex}".format (obj)) # 输出 "Value in hex: 0x2a"
print("Value in binary: {:bin}".format (obj)) # 输出 "Value in binary: 0b101010"
在此示例中,我们定义了一个名为 MyClass 的类,它有一个属性 value 表示对象的值。通过重载 __format__ 方法,我们定义了对象被格式化时的输出形式,使得可以通过 {} 格式化字符串时指定不同的格式。
__bytes__(self)
__bytes__ 方法定义了该类的实例被转换成字节序列的方式。我们可以通过重载这个方法,自定义对象被转换成字节序列的逻辑。
1
2
3
4
5
6
7
8
9
10
class MyClass:
def __init__(self, value):
self.value = value
def __bytes__(self):
return bytes ([self.value])
obj = MyClass(65)
print(bytes (obj)) # 输出 b'A'
在此示例中,我们定义了一个名为 MyClass 的类,它有一个属性 value 表示对象的值。通过重载 __bytes__ 方法,我们定义了对象被转换成字节序列的逻辑。
__getattr__(self, name)
__getattr__ 方法在对象的属性未找到时被调用。我们可以利用 __getattr__ 方法动态地返回对象的属性值或者执行一些额外的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass:
x = 10
def __getattr__(self, name):
if name == 'y':
return 20
else:
raise AttributeError ('Attribute not found')
obj = MyClass()
print(obj.x) # 输出 10
print(obj.y) # 输出 20
print(obj.z) # 抛出 AttributeError 异常
在此示例中,如果尝试访问 obj 对象中不存在的属性 z,则会抛出 AttributeError 异常。但是如果访问 obj 对象中不存在的属性 y,则会返回一个固定的值 20,这是通过 __getattr__ 方法实现的。
__getattribute__(self, name)
__getattribute__ 方法在对象的属性被访问时被调用。它与 __getattr__ 方法类似,但是不同之处在于,它必须返回一个值,否则将抛出异常。
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass:
x = 10
def __getattribute__(self, name):
if name == 'y':
return 20
else:
return object.__getattribute__(self, name)
obj = MyClass()
print(obj.x) # 输出 10
print(obj.y) # 输出 20
print(obj.z) # 抛出 AttributeError 异常
在此示例中,如果尝试访问 obj 对象中不存在的属性 z,则会抛出 AttributeError 异常。但是如果访问 obj 对象中不存在的属性 y,则会返回一个固定的值 20,这是通过 __getattribute__ 方法实现的。
__setattr__(self, name, value)
__setattr__ 方法在对象的属性被设置时被调用。我们可以利用 setattr 方法动态地修改对象的属性值或者执行一些额外的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass:
x = 10
def __setattr__(self, name, value):
if name == 'y':
raise AttributeError ('Cannot set attribute')
else:
object.__setattr__(self, name, value)
obj = MyClass()
obj.x = 20
print(obj.x) # 输出 20
obj.y = 30 # 抛出 AttributeError 异常
在此示例中,如果尝试修改 obj 对象中特定的属性 y,则会抛出 AttributeError 异常。但是如果修改 obj 对象中其他的属性,例如 x,则不会有异常发生。
__delattr__(self, name)
__delattr__ 方法在对象的属性被删除时被调用。我们可以利用 __delattr__ 方法动态地删除对象的属性或者执行一些额外的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
class MyClass:
x = 10
def __delattr__(self, name):
if name == 'y':
raise AttributeError ('Cannot delete attribute')
else:
object.__delattr__(self, name)
obj = MyClass()
del obj.x
print(hasattr (obj, 'x')) # 输出 False
del obj.y # 抛出 AttributeError 异常
在此示例中,如果尝试删除 obj 对象中特定的属性 y,则会抛出 AttributeError 异常。但是如果删除 obj 对象中其他的属性,例如 x,则不会有异常发生。
__eq__(self, other)
__eq__ 方法定义了相等操作符(==)的实现。我们可以通过重载这个方法,自定义对象相等的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector:
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
v1 = Vector(1, 2)
v2 = Vector(1, 2)
v3 = Vector(2, 3)
print(v1 == v2) # 输出 True
print(v1 == v3) # 输出 False
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __eq__ 方法,我们定义了对象相等的比较方式,当两个向量的 x 和 y 值都相等时,它们被认为是相等的。
__ne__(self, other)
__ne__ 方法定义了不等于操作符(!=)的实现。我们可以通过重载这个方法,自定义对象不等的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __ne__(self, other):
return not self.__eq__(other)
v1 = Vector(1, 2)
v2 = Vector(1, 2)
v3 = Vector(2, 3)
print(v1 != v2) # 输出 False
print(v1 != v3) # 输出 True
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __ne__ 方法,我们定义了对象不等的比较方式,当两个向量的 x 和 y 值至少有一个不相等时,它们被认为是不相等的。
__lt__(self, other)
__lt__ 方法定义了小于操作符(<)的实现。我们可以通过重载这个方法,自定义对象大小的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector:
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
v1 = Vector(1, 2)
v2 = Vector(2, 3)
v3 = Vector(0, 1)
print(v1 < v2) # 输出 True
print(v1 < v3) # 输出 False
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __lt__ 方法,我们定义了对象大小的比较方式,当一个向量在 x 和 y 坐标上都小于另一个向量时,它被认为是小于另一个向量。
__le__(self, other)
__le__ 方法定义了小于等于操作符(<=)的实现。我们可以通过重载这个方法,自定义对象大小的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __le__(self, other):
return self.x <= other.x and self.y <= other.y
v1 = Vector(1, 2)
v2 = Vector(2, 3)
v3 = Vector(0, 1)
print(v1 <= v2) # 输出 True
print(v1 <= v3) # 输出 False
print(v1 <= v1) # 输出 True
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __le__ 方法,我们定义了对象大小的比较方式,当一个向量在 x 和 y 坐标上都小于等
__gt__(self, other)
__gt__ 方法定义了大于操作符(>)的实现。我们可以通过重载这个方法,自定义对象大小的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector:
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
v1 = Vector(2, 3)
v2 = Vector(1, 2)
v3 = Vector(3, 4)
print(v1 > v2) # 输出 True
print(v1 > v3) # 输出 False
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __gt__ 方法,我们定义了对象大小的比较方式,当一个向量在 x 和 y 坐标上都大于另一个向量时,它被认为是大于另一个向量。
__ge__(self, other)
__ge__ 方法定义了大于等于操作符(>=)的实现。我们可以通过重载这个方法,自定义对象大小的比较方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __ge__(self, other):
return self.x >= other.x and self.y >= other.y
v1 = Vector(2, 3)
v2 = Vector(1, 2)
v3 = Vector(3, 4)
print(v1 >= v2) # 输出 True
print(v1 >= v3) # 输出 False
print(v1 >= v1) # 输出 True
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __ge__ 方法,我们定义了对象大小的比较方式,当一个向量在 x 和 y 坐标上大于等于另一个向量时,它被认为是大于等于另一个向量。
__add__(self, other)
__add__ 方法定义了加法操作符(+)的实现。我们可以通过重载这个方法,自定义对象相加的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
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)
v3 = v1 + v2
print(v3.x, v3.y) # 输出 4 6
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __add__ 方法,我们定义了对象相加的逻辑,将两个向量在 x 和 y 坐标上分别相加得到一个新的向量。
__sub__(self, other)
__sub__ 方法定义了减法操作符(-)的实现。我们可以通过重载这个方法,自定义对象相减的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
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)
v3 = v1 - v2
print(v3.x, v3.y) # 输出 2 2
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __sub__ 方法,我们定义了对象相减的逻辑,将两个向量在 x 和 y 坐标上分别相减得到一个新
__mul__(self, other)
__mul__ 方法定义了乘法操作符(*)的实现。我们可以通过重载这个方法,自定义对象相乘的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
self.y = y
def __mul__(self, other):
return Vector(self.x * other.x, self.y * other.y)
v1 = Vector(2, 3)
v2 = Vector(3, 4)
v3 = v1 * v2
print(v3.x, v3.y) # 输出 6 12
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __mul__ 方法,我们定义了对象相乘的逻辑,将两个向量在 x 和 y 坐标上分别相乘得到一个新的向量。
__truediv__(self, other)
__truediv__ 方法定义了真除法操作符(/)的实现。我们可以通过重载这个方法,自定义对象相除的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __truediv__(self, other):
return Vector(self.x/other.x, self.y/other.y)
v1 = Vector(6, 8)
v2 = Vector(2, 4)
v3 = v1 /v2
print(v3.x, v3.y) # 输出 3.0 2.0
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __truediv__ 方法,我们定义了对象相除的逻辑,将两个向量在 x 和 y 坐标上分别相除得到一个新的向量。
__floordiv__(self, other)
__floordiv__ 方法定义了整除法操作符(//)的实现。我们可以通过重载这个方法,自定义对象整除的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __floordiv__(self, other):
return Vector(self.x//other.x, self.y//other.y)
v1 = Vector(7, 9)
v2 = Vector(2, 4)
v3 = v1 //v2
print(v3.x, v3.y) # 输出 3 2
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __floordiv__ 方法,我们定义了对象整除的逻辑,将两个向量在 x 和 y 坐标上分别整除得到一个新的向量。
__mod__(self, other)
__mod__ 方法定义了取模操作符(%)的实现。我们可以通过重载这个方法,自定义对象取模的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __mod__(self, other):
return Vector(self.x % other.x, self.y % other.y)
v1 = Vector(7, 9)
v2 = Vector(2, 4)
v3 = v1 % v2
print(v3.x, v3.y) # 输出 1 1
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __mod__ 方法,我们定义了对象取模的逻辑,将两个向量在 x 和 y 坐标上分别取模得到一个新的向量。
__pow__(self, other [, modulo])
__pow__ 方法定义了幂次方操作符(**)的实现。我们可以通过重载这个方法,自定义对象的幂运算逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __pow__(self, other):
return Vector(self.x ** other.x, self.y ** other.y)
v1 = Vector(2, 3)
v2 = Vector(3, 2)
v3 = v1 ** v2
print(v3.x, v3.y) # 输出 8 9
在此示例中,我们定义了一个名为 Vector 的类,它有两个属性 x 和 y。通过重载 __pow__ 方法,我们定义了对象的幂运算逻辑,将两个向量在 x 和 y 坐标上分别进行幂运算得到一个新的向量。
__and__(self, other)
__and__ 方法定义了按位与操作符(&)的实现。我们可以通过重载这个方法,自定义对象按位与运算的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
class BinaryNumber:
def __init__(self, num):
self.num = num
def __and__(self, other):
return BinaryNumber(self.num & other.num)
b1 = BinaryNumber(0b1100)
b2 = BinaryNumber(0b1010)
b3 = b1 & b2
print(bin (b3.num)) # 输出 '0b1000'
在此示例中,我们定义了一个名为 BinaryNumber 的类,它表示一个二进制数。通过重载 __and__ 方法,我们定义了对象按位与运算的逻辑,将两个二进制数进行按位与运算得到一个新的二进制数。
__or__(self, other)
__or__ 方法定义了按位或操作符(|)的实现。我们可以通过重载这个方法,自定义对象按位或运算的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
class BinaryNumber:
def __init__(self, num):
self.num = num
def __or__(self, other):
return BinaryNumber(self.num | other.num)
b1 = BinaryNumber(0b1100)
b2 = BinaryNumber(0b1010)
b3 = b1 | b2
print(bin (b3.num)) # 输出 '0b1110'
在此示例中,我们定义了一个名为 BinaryNumber 的类,它表示一个二进制数。通过重载 __or__ 方法,我们定义了对象按位或运算的逻辑,将两个二进制数进行按位或运算得到一个新的二进制数。
__xor__(self, other)
__xor__ 方法定义了按位异或操作符(^)的实现。我们可以通过重载这个方法,自定义对象按位异或运算的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
class BinaryNumber:
def __init__(self, num):
self.num = num
def __xor__(self, other):
return BinaryNumber(self.num ^ other.num)
b1 = BinaryNumber(0b1100)
b2 = BinaryNumber(0b1010)
b3 = b1 ^ b2
print(bin (b3.num)) # 输出 '0b0110'
在此示例中,我们定义了一个名为 BinaryNumber 的类,它表示一个二进制数。通过重载 __xor__ 方法,我们定义了对象按位异或运算的逻辑,将两个二进制数进行按位异或运算得到一个新的二进制数。 下面是这些魔法方法的使用实例:
__lshift__(self, other)
__lshift__ 方法定义了左移操作符(«)的实现。我们可以通过重载这个方法,自定义对象的左移运算逻辑。
1
2
3
4
5
6
7
8
9
10
11
class BinaryNumber:
def __init__(self, num):
self.num = num
def __lshift__(self, other):
return BinaryNumber(self.num << other)
b1 = BinaryNumber(0b1100)
b2 = b1 << 2
print(bin (b2.num)) # 输出 '0b110000'
在此示例中,我们定义了一个名为 BinaryNumber 的类,它表示一个二进制数。通过重载 __lshift__ 方法,我们定义了对象的左移运算逻辑,将一个二进制数左移指定的位数得到一个新的二进制数。
__rshift__(self, other)
__rshift__ 方法定义了右移操作符(»)的实现。我们可以通过重载这个方法,自定义对象的右移运算逻辑。
1
2
3
4
5
6
7
8
9
10
11
class BinaryNumber:
def __init__(self, num):
self.num = num
def __rshift__(self, other):
return BinaryNumber(self.num >> other)
b1 = BinaryNumber(0b1100)
b2 = b1 >> 2
print(bin (b2.num)) # 输出 '0b0011'
在此示例中,我们定义了一个名为 BinaryNumber 的类,它表示一个二进制数。通过重载 __rshift__ 方法,我们定义了对象的右移运算逻辑,将一个二进制数右移指定的位数得到一个新的二进制数。
下面是这些魔法方法的使用示例:
__len__(self)
__len__ 方法定义了该类的实例长度,即元素的个数。我们可以通过重载这个方法,自定义对象的长度逻辑。
1
2
3
4
5
6
7
8
9
10
class MyList:
def __init__(self, elements):
self.elements = elements
def __len__(self):
return len (self.elements)
my_list = MyList([1, 2, 3, 4, 5])
print(len (my_list)) # 输出 5
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __len__ 方法,我们定义了对象的长度逻辑,返回列表元素的个数。
__getitem__(self, key)
__getitem__ 方法定义了该类的实例通过索引访问元素的方式。我们可以通过重载这个方法,自定义对象索引访问元素的逻辑。
1
2
3
4
5
6
7
8
9
10
class MyList:
def __init__(self, elements):
self.elements = elements
def __getitem__(self, index):
return self.elements [index]
my_list = MyList([1, 2, 3, 4, 5])
print(my_list [2]) # 输出 3
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __getitem__ 方法,我们定义了对象索引访问元素的逻辑,返回列表指定索引位置上的元素。
__setitem__(self, key, value)
__setitem__ 方法定义了该类的实例通过索引设置元素的方式。我们可以通过重载这个方法,自定义对象索引设置元素的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
class MyList:
def __init__(self, elements):
self.elements = elements
def __setitem__(self, index, value):
self.elements [index] = value
my_list = MyList([1, 2, 3, 4, 5])
my_list [2] = 10
print(my_list.elements) # 输出 [1, 2, 10, 4, 5]
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __setitem__ 方法,我们定义了对象索引设置元素的逻辑,将列表指定索引位置上的元素赋值为新值。
__delitem__(self, key)
__delitem__ 方法定义了该类的实例通过索引删除元素的方式。我们可以通过重载这个方法,自定义对象索引删除元素的逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
class MyList:
def __init__(self, elements):
self.elements = elements
def __delitem__(self, index):
del self.elements [index]
my_list = MyList([1, 2, 3, 4, 5])
del my_list [2]
print(my_list.elements) # 输出 [1, 2, 4, 5]
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __delitem__ 方法,我们定义了对象索引删除元素的逻辑,将列表指定索引位置上的元素删除。
__iter__(self)
__iter__ 方法定义了该类的实例可迭代的方式。我们可以通过重载这个方法,自定义对象的迭代逻辑。
1
2
3
4
5
6
7
8
9
10
11
class MyList:
def __init__(self, elements):
self.elements = elements
def __iter__(self):
return iter (self.elements)
my_list = MyList([1, 2, 3, 4, 5])
for item in my_list:
print(item)
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __iter__ 方法,我们定义了对象的迭代逻辑,使得对象可以被 for 循环遍历。
__reversed__(self)
__reversed__ 方法定义了该类的实例反向迭代。我们可以通过重载这个方法,自定义对象的反向迭代逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyList:
def __init__(self, elements):
self.elements = elements
def __iter__(self):
return iter (self.elements)
def __reversed__(self):
return reversed(self.elements)
my_list = MyList([1, 2, 3, 4, 5])
for item in reversed(my_list):
print(item)
在此示例中,我们定义了一个名为 MyList 的类,它有一个属性 elements 表示列表的元素。通过重载 __iter__ 和 __reversed__ 方法,我们定义了对象的迭代逻辑和反向迭代逻辑,使得对象可以被 for 循环正向或反向遍历。