常用魔法方法
1、功能性
(1)__ getitem__与__setitem__
这两个函数的意义是使对象实现与列表或字典等容器类相同的操作,实现直接读取和修改数据
- 当对 对象 使用索引操作符([])时,Python会调用该对象的**__ getitem__**方法来获取对应索引的值。
- **__ getitem__**方法通常用于自定义容器类(如列表、字典、集合等)以支持索引操作。但它也可以在自定义类中使用,为对象提供类似于序列或映射的行为。
例子1:
class GetTest(object):
def __init__(self):
self.info = {
'name':'Yasoob',
'country':'Pakistan',
'number':12345812
}
def __getitem__(self,i):
return self.info[i]
>>> foo = GetTest()
>>> foo['name']
'Yasoob'
>>> foo['number']
12345812
如果没有__getitem__则报错:
>>> foo['name']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'GetTest' object has no attribute '__getitem__'
例子2:
class MyContainer:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
container = MyContainer([1, 2, 3, 4, 5])
# 使用索引操作符获取值
print(container[0]) # 输出:1
print(container[2]) # 输出:3
- __setitem__方法用于设置对象的元素
例子1:
class MyList:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
my_list = MyList([1, 2, 3, 4, 5])
print(my_list[2]) # 输出 3
my_list[2] = 42
print(my_list[2]) # 输出 42
(2)call
- **call()**方法可以让类的实例具有类似于函数的行为
- 对一个对象使用函数调用操作符()时,Python会调用该对象的**call**方法
例子1:
class Adder:
def __init__(self, num):
self.num = num
def __call__(self, x):
return self.num + x
adder = Adder(5)
# 使用对象像函数一样调用
result = adder(10)
print(result) # 输出:15
直接调用实例化后生成的对象,以调用函数的形式表示,相当于调用了对象的__call__函数。
例子2:
class A(object):
def __call__(self, *args, **kwargs):
print('call....')
a = A()
a() # 自动调用__call__()
(3)str
- 用于返回对象的字符串表示形式
- 当对一个对象使用str()函数或print()函数时,Python会调用该对象的**str**方法来获取其字符串表示。
例子1:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person: {self.name}, Age: {self.age}"
person = Person("Alice", 30)
# 使用str()函数获取对象的字符串表示形式
print(str(person)) # 输出:Person: Alice, Age: 30
# 使用print()函数打印对象时,也会调用__str__方法
print(person) # 输出:Person: Alice, Age: 30
当将对象当作字符串时,调用__str__函数,输出的字符串即该函数的返回值
例子2:
class Cat:
def __init__(self, name, sex):
self.name = name
self.sex = sex
def __str__(self):
return f"我是一只可爱的小{self.sex}猫咪,我的名字是{self.name}"
>>> cat = Cat("小白", "公")
>>> print(cat)
我是一只可爱的小公猫咪,我的名字是小白
(4)len
- 用于返回对象的长度或大小
- 对一个对象使用len()函数时,会调用该对象的**len**方法来获取其长度
例子1:
class MyList:
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
my_list = MyList([1, 2, 3, 4, 5])
# 使用len()函数获取对象的长度
print(len(my_list)) # 输出:5
**len**方法的意义在于提供一种获取对象长度的标准方式,使得对象能够以类似于序列或容器的方式来使用,**所用容器类(列表、字典、集合、元组)**皆可用
其返回值必须是整型
例子2:
class List:
def __init__(self):
self.num = []
def add(self, x):
self.num.append(x)
def __len__(self):
return len(self.num)
>>> l = List()
>>> l.add(2)
>>> print(len(l))
(5)iter 和 next
- __iter__方法返回一个可迭代对象,__next__方法用于获取下一个元素
- __next__用来支持__iter__方法的迭代,二者一般成对使用
例子1:
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
value = self.data[self.index]
self.index += 1
return value
else:
raise StopIteration
my_iterator = MyIterator([1, 2, 3, 4, 5])
# 使用iter()函数获取迭代器对象
iterator = iter(my_iterator)
# 使用next()函数遍历迭代器
try:
while True:
print(next(iterator))
except StopIteration:
pass
2、提示性(用于交互)
(1)repr
- 与**str方法类似,repr方法也返回一个字符串,但它的目的是为了产生对象的一种“可读性好”的表示形式**,通常用于调试和开发阶段,以便开发者了解对象的状态和属性
例子1:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
point = Point(3, 4)
# 使用repr()函数获取对象的官方字符串表示形式
print(repr(point)) # 注意这里不是用点,而是将对象作为repr函数的输入
# 输出:Point(3, 4)
# 在交互式环境中输入对象时,也会调用__repr__方法
point # 输出:Point(3, 4)
例子2:
class MyClass:
def __init__(self, value):
self.value = value
def __repr__(self):
return f"MyClass({self.value})"
obj = MyClass(42)
print(obj) # 输出 "MyClass(42)"