流畅的python学习笔记(二):特殊方法的使用


特殊方法的存在是为了被python解释器调用的,你自己并不需要调用他们。也就是说没有 my_object.len() 这种写法,而应该使用 len(my_object)。
在执行 len(my_object) 的时候,如果 my_object 是一个自定义类的对象,那么Python 会自己去调用其中由你实现的 len 方法。

'''
通常你的代码无需直接使用特殊方法。除非有大量的元编程存在,直接调用特殊方法的频率应该远远低于你去实现它们的次数。
唯一的例外可能是 __init__ 方法,你的代码里可能经常会用到它,目的是在你自己的子类的 __init__ 方法中调用超类的构造器
'''
一个简单的二维向量类
from math import hypot


class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Vector({}, {})'.format(self.x, self.y)

    def __abs__(self):
        return hypot(self.x, self.y)

    def __bool__(self):
        return bool(self.x or self.y)

    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)

虽然代码里有 6 个特殊方法,但这些方法(除了 init)并不会在这个类自身的代码中使用。即便其他程序要使用这个类的这些方法,也不会直接调用它们,一般只有 Python 的解释器会频繁地直接调用这些方法。接下来看看每个特殊方法的实现。

字符串表现形式
def __repr__(self):
	"""
		__repr__: 类似于len, repr把一个对象用字符串的形式表达出来以便辨认。
    	repr通过__repr__这个特殊方法来得到一个对象的字符串表现形式,如果没有实现该特殊方法,输出结果为如下形式:
    	<__main__.Vector object at 0x000002722A5B6610>
    	
		__repr__ 所返回的字符串应该准确、无歧义,并且尽可能表达出如何用代码创建出这个被打印的对象。
		因此这里使用了类似调用对象构造器的表达形式
		
		__repr__ 和 __str__ 的区别在于,后者是在 str() 函数被使用,
		或是在用 print 函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好
		如果你只想实现这两个特殊方法中的一个,__repr__ 是更好的选择
    """
        return 'Vector({}, {})'.format(self.x, self.y)
        
vector = Vector(1, 2)
print(vector) # Vector(1, 2)
算术运算符
'''
	通过 __add__ 和 __mul__,示例向量类带来了 + 和 * 这两个算术运算符
'''
if __name__ == '__main__':
    vector1 = Vector(1, 2)
    vector2 = Vector(1, 4)
    print(vector1 + vector2) # Vector(2, 6)
    print(vector1 * 3) # Vector(3, 6)
自定义布尔值
'''
	默认情况下,我们自己定义的类的实例总被认为是真的,除非这个类对__bool__ 或者 __len__ 函数有自己的实现。
	bool(x) 的背后是调用x.__bool__() 的结果;
	如果不存在 __bool__ 方法,那么 bool(x)会尝试调用 x.__len__()。
	若返回 0,则 bool 会返回 False;否则返回 True
	
	我们对 __bool__ 的实现很简单,如果一个向量的模是 0,那么就返回False,其他情况则返回 True。
	因为 __bool__ 函数的返回类型应该是布尔型,所以我们通过 bool(abs(self)) 把模值变成了布尔值
'''
    def __bool__(self):
        return bool(self.x or self.y)

通过实现特殊方法,自定义数据类型可以表现得跟内置类型一样,从而让我们写出更具表达力的代码——或者说,更具 Python 风格的代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值