《疯狂Python讲义》之Python类的特殊方法

常见的特殊方法

重写__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()函数执行向上取整
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值