python特殊方法的重要用途

一、模拟数值类型

有几种特殊方法可以使用户对象响应+、*等运算符,接下来通过实现一个二维向量类来对此进行说明。

一个简单的二维向量应实现向量加法、计算向量的模、向量的标量积的运算

import math

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 用于表示对象的状态或内容
    def __repr__(self):
        return f'Vector({self.x!r}, {self.y!r})'

    # 用于计算返回向量的模
    def __abs__(self):
        # math.hypot返回所有参数平方和的平方根
        return math.hypot(self.x, self.y)

    def __bool__(self):
        return bool(abs(self))

    # 返回向量的和
    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)

    # 返回向量的标量积
    def __mul__(self, other):
        return Vector(self.x * other, self.y * other)

v1 = Vector(2, 4)
v2 = Vector(2, 1)
print(v1 + v2)
# output: Vector(4, 5)
print(abs(Vector(3, 4)))
# output: 5.0
print(v1 * 3)
# output: Vector(6, 12)

示例使用了__repr__、__abs__、__add__、__mul__等特殊方法为Vector类实现了上述的运算。

补充:其中__add__、__mul__这两个方法创建并返回一个新的Vector实例,没有修改运算对象,只是读取self、other,这是中缀运算符的预期行为,即创建新对象,不修改运算对象。

二、对象的字符串表现形式

上述示例使用了特殊方法__repr__供内置函数repr()调用,获取对象的字符串表现形式,若不重构该方法,Vector类在显示台默认返回对象的类名称和对象的地址,如:

Vector类中__repr__方法中f字符串使用 !r 以标准的形式显示属性。

补充:

1.与__repr__方法形成对照的是__str__方法由内置函数str()调用,在背后供print函数使用,返回对终端用户友好的字符串。

2.repr()函数与str函数有什么区别呢?

1.repr()函数:将值转化为供解释器读取的字符串形式;str()函数:将值转化为适于人阅读的字符串的形式

2.命令行下直接输出对象调用的是repr方法;print输出调用的是str方法

3.除字符串类型外两者并无区别,对于字符串类型,repr方法会在外层多加一层引号,在eval操作时会特别有用

三、对象的布尔值

python有一个bool类型,在if、while语句的条件表达式,或and、or和not的运算对象这些需要布尔值的地方对对象进行处理,python会通过调用bool(x)来判断x的True或False。

默认情况下,用户定义的实例都是真值,除非实现了__bool__或__len__方法。bool(x)调用x.__bool__()以其返回的结果为准,若没有实现__bool__方法,也尝试调用x.__len__(),若该方法返回0,则bool函数返回False,否则返回True。

在上述示例中,因为__bool__方法必须返回一个bool值,我们使用bool(abs(self))将向量的模转换成bool值,如果向量模为0,则返回False,否则返回True。

四、实现容器

容器类型对特殊方法的使用:

1.最顶部的抽象基类均只有一个特殊方法,每一个容器类型均应实现如下事项:

(1)Iterable:__iter__,要支持for、拆包和其他迭代方式

(2)Sized:__len__,要支持内置函数len

(3)Container:__contains__,要支持in运算符

2.collection有3个重要的专用接口:

(1)Sequence:规范list和str等内置类型的接口

(2)Mapping:被dict、collections.defaultdict等实现

(3)Set:是set和frozenset两个内置类型的接口

注:只有Sequence实现了Reversible,因为序列支持以任意顺序排列内容,Mapping和Set不需要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值