常见的特殊方法
重写__repr__方法
repr()是Python类中的一个特殊方法,由于object类已提供了该方法,而所有Python类都是object类的子类,因此所有的Python对象都具有__repr__()方法。
当程序需要将任何对象与字符串进行连接时,可先调用__repr__()方法将对象转换成字符串,然后将两个字符串连接在一起
object类提供的__repr__()方法总是返回该对象实现类的“类名+object at+内存地址”值。
class Apple:
# 实现构造器
def __init__(self, color, weight):
self.color = color;
self.weight = weight;
# 重写toString()方法,用于实现Apple对象的“自我描述”
def __repr__(self):
return "Apple[color=" + self.color +\
", weight=" + str(self.weight) + "]"
a = Apple("红色" , 5.68)
# 打印Apple对象
print(a)
析构方法__del__
与__init__()方法对应的是__del__()方法,init()方法用于初始化Python对象,而__del__()则用于销毁Python对象----在任何Python对象将要被系统回收时,系统都会自动调用该对象的__del__()方法。
__dir__方法
对象的__dir__()方法用于列出该对象内部的所有属性(包括方法)名,该方法将会返回包含所有属性(方法)的序列。
__dict__属性
__dict__属性用于查看对象内部存储的所有属性名和属性值组成的字典,通常程序直接使用该属性即可。
getattr、__setattr__等
- __ getattribute__(self,name):当程序访问对象的name属性时被自动调用
- __ getattr__(self,name):当程序访问对象的name属性且该属性不存在时被自动调用
- __ setattr__(self,name,value):当程序对对象的name属性赋值时被自动调用
- __ delattr__(self,name):当程序删除对象的name属性时被自动调用
与反射相关的属性和方法
动态操作属性
在动态检查对象是否包含某些属性相关的函数有如下几个:
- hasattr(obj,name):检查obj对象是否包含名为name的属性或方法
- getattr(object,name[,default]):
- setattr(obj,name,value,/):将obj对象的name属性设为value
__call__属性
程序可通过判断该属性是否包含__call__属性来确定它是否可调用
与序列相关的特殊方法
序列相关方法
序列最重要的特征就是可包含多个元素,因此和序列有关的特殊方法有如下一个:
- __len __ (self):该方法的返回值决定序列中元素的个数
- __getitem __(self,key):该方法获取指定索引对应的元素
- __contains __(self,item):该方法判断序列是否包含指定元素
- __setitem __(self,key,value):该方法设置指定索引对应的元素
- __delitem __(self,key):该方法删除指定索引对应的元素
def check_key (key):
'''
该函数将会负责检查序列的索引,该索引必须是整数值,否则引发TypeError
且程序要求索引必须为非负整数,否则引发IndexError
'''
if not isinstance(key, int): raise TypeError('索引值必须是整数')
if key < 0: raise IndexError('索引值必须是非负整数')
if key >= 26 ** 3: raise IndexError('索引值不能超过%d' % 26 ** 3)
class StringSeq:
def __init__(self):
# 用于存储被修改的数据
self.__changed = {}
# 用于存储已删除元素的索引
self.__deleted = []
def __len__(self):
return 26 ** 3
def __getitem__(self, key):
'''
根据索引获取序列中元素
'''
check_key(key)
# 如果在self.__changed中找到已经修改后的数据
if key in self.__changed :
return self.__changed[key]
# 如果key在self.__deleted中,说明该元素已被删除
if key in self.__deleted :
return None
# 否则根据计算规则返回序列元素
three = key // (26 * 26)
two = ( key - three * 26 * 26) // 26
one = key % 26
return chr(65 + three) + chr(65 + two) + chr(65 + one)
def __setitem__(self, key, value):
'''
根据索引修改序列中元素
'''
check_key(key)
# 将修改的元素以key-value对的形式保存在__changed中
self.__changed[key] = value
def __delitem__(self, key):
'''
根据索引删除序列中元素
'''
check_key(key)
# 如果__deleted列表中没有包含被删除key,添加被删除的key
if key not in self.__deleted : self.__deleted.append(key)
# 如果__changed中包含被删除key,删除它
if key in self.__changed : del self.__changed[key]
# 创建序列
sq = StringSeq()
# 获取序列的长度,实际上就是返回__len__()方法的返回值
print(len(sq))
print(sq[26*26])
# 打印没修改之后的sq[1]
print(sq[1]) # 'AAB'
# 修改sq[1]元素
sq[1] = 'fkit'
# 打印修改之后的sq[1]
print(sq[1]) # 'fkit'
# 删除sq[1]
del sq[1]
print(sq[1]) # None
# 再次对sq[1]赋值
sq[1] = 'crazyit'
print(sq[1]) # crazyit
实现迭代器
使用for循环遍历列表、元组和字典等,这些对象都是可迭代的,因此它们都属于迭代器。
- __iter __(self):该方法返回一个迭代器(iterator),迭代器必须包含一个__next __()方法,该方法返回迭代器的下一个元素
- __reversed __(self):该方法主要为内建的reversed()反转函数提供支持,当程序调用reversed()函数对指定迭代器执行反转时,实际上是由该方法实现的。
扩展列表、元组和字典
如果程序明确需要一个特殊的列表、元组或字典类,有两种选择:
- 自己实现序列、迭代器等各种方法,自己来实现这个特殊的类
- 扩展系统已有的列表、元组或字典
生成器
生成器和迭代器的功能非常相似,它也会提供__next __()方法,这意味着程序同样可调用内置的next()函数来获取生成器的下一个值,也可以使用for循环来遍历生成器。
生成器与迭代器的区别在于:迭代器通常是先定义一个迭代器类,然后通过创建实例来创建迭代器;而生成器则是先定义衣蛾包含yield语句的函数,然后通过调用该函数来创建生成器
创建生成器
创建生成器需要两步操作:
- 定义一个包含yield语句的函数
- 调用第一步创建的函数得到生成器
def test(val, step):
print("--------函数开始执行------")
cur = 0
# 遍历0~val
for i in range(val):
# cur添加i*step
cur += i * step
yield cur
# print(cur, end=' ')
# 执行函数,返回生成器
t = test(10, 2)
print('=================')
# 获取生成器的第一个值
print(next(t)) # 0,生成器“冻结”在yield处
print(next(t)) # 2,生成器再次“冻结”在yield处
for ele in t:
print(ele, end=' ')
# 再次创建生成器
t = test(10, 1)
# 将生成器转换成列表
print(list(t))
# 再次创建生成器
t = test(10, 3)
# 将生成器转换成列表
print(tuple(t))
yield cur语句的作用有两点:
- 每次返回一个值,有点类似于return语句
- 冻结执行,程序每次执行到yield语句时就会被暂停
Python主要提供了两种方式来创建生成器:
- 使用for循环的生成器推导式
- 调用带yield语句的生成器函数
生成器的方法
为了实现生成器与“外部程序”动态地交换数据,需要借助于生成器的send()方法,该方法用于获取生成器所生成的下一个值,并将生成器“冻结”在yield语句处,但send()方法啊可以接受一个参数,该参数被发送给生成器函数。
- 外部程序通过send()方法发送数据
- 生成器函数使用yield语句接收数据
此外,生成器还提供了两个常用方法: - close():该方法用于停止生成器
- throw():该方法用于在生成器内部引发一个异常
运算符重载的特殊方法
与数值运算符相关的特殊方法
- object.__add __(self, other):加法运算,为“+”运算符提供支持
- object.__sub __(self, other):减法运算,为“-”运算符提供支持
- object.__mul __(self, other):乘法运算,为“*”运算符提供支持
- object.__matmul __(self, other):矩阵乘法,为“@”运算符提供支持
- object.__truediv __(self, other):除法运算,为“/”运算符提供支持
- object.__floordiv __(self, other):整除运算,为“//”运算符提供支持
- object.__mod __(self, other):求余运算,为“%”运算符提供支持
- object.__divmod __(self, other):求余运算,为divmod运算符提供支持
- object.__pow __(self, other[,modulo]):乘方运算,为“**”运算符提供支持
- object.__lshift __(self, other):左移运算,为“<<”运算符提供支持
- object.__rshift __(self, other):右移运算,为“>>”运算符提供支持
- object.__and __(self, other):按位与运算,为“&”运算符提供支持
- object.__xor __(self, other):按位异或运算,为“^”运算符提供支持
- object.__or __(self, other):按位或运算,为“|”运算符提供支持
此外,Python还支持各种扩展后的复制运算符
- object.__iadd __(self, other):为“+=”运算符提供支持
- object.__isub __(self, other):为“-=”运算符提供支持
- object.__imul __(self, other):为“*=”运算符提供支持
- object.__imatmul __(self, other):为“@=”运算符提供支持
- object.__itruediv __(self, other):为“/=”运算符提供支持
- object.__ifloordiv __(self, other):整除运算,为“//=”运算符提供支持
- object.__imod __(self, other):为“%=”运算符提供支持
- object.__ipow __(self, other[,modulo]):为“**=”运算符提供支持
- object.__ilshift __(self, other):为“<<=”运算符提供支持
- object.__irshift __(self, other):为“>>=”运算符提供支持
- object.__iand __(self, other):为“&=”运算符提供支持
- object.__ixor __(self, other):为“^=”运算符提供支持
- object.__ior __(self, other):为“|=”运算符提供支持
与比较运算符相关的特殊方法
- object.__lt __(self, other):为“<”运算符提供支持
- object.__le __(self, other):为“<=”运算符提供支持
- object.__eq __(self, other):为“==”运算符提供支持
- object.__ne __(self, other):为“!=”运算符提供支持
- object.__gt __(self, other):为“>”运算符提供支持
- object.__ge __(self, other):为“>=”运算符提供支持
与单目运算符相关的特殊方法
- object.__neg __(self):为单目求负(-)运算符提供支持
- object.__pos __(self):为单目求正(+)运算符提供支持
- object.__invert __(self):为单目取反(~)运算符提供支持
与类型转换相关的特殊方法
- object.__str __(self):对应于调用内置的str()函数将该对象转换成字符串
- object.__bytes __(self):对应于调用内置的bytes()函数将该对象转换成字节内容,返回bytes对象
- object.__complex __(self):对应于调用内置的complex()函数将该对象转换成复数,返回complex对象
- object.__int __():对应于调用内置的int()函数对象转换成整数,返回int对象
- object.__float __():对应于调用内置的float()函数对象转换成整数,返回float对象
与常见的内建函数相关的特殊方法
- object.__format __(self,format_spec):对应于调用内置的format()函数将对象转换成格式化字符串
- object.__hash __(self):对应于调用内置的hash()函数来获取该对象的hash码
- object.__abs __(self):对应于调用内置的abs()函数返回绝对值
- object.__round __(self[, ndigits]):对应于调用内置的round()函数执行四舍五入取整
- object.__trunc __(self):对应于调用内置的trunc()函数执行截断取整
- object.__floor __(self):对应于调用内置的floor()函数执行向下取整
- object.__ceil __(self):对应于调用内置的ceil()函数执行向上取整