1.如何使用特殊方法
特殊方法的存在是为了被Ppython解释器调用的,我们并不需要调用它们。在执行len(my_object)的时候,如果my_object是一个自定义类的对象,那么Python会自己去调用其中由你实现的(__len__)方法。
很多时候,特殊方法的调用是隐式的,比如:for i in x ----->iter(x)------>x.__iter__()
通常你的代码无需直接调用特殊方法,除非有大量的元编程存在
通过内置的函数(例如len,iter,str等)来使用特殊方法是最好的选择,这些内置函数不仅调用特殊方法,通常还速度更快
2.模拟数值类型
实现一个二维向量(Vector)类
实现效果:
代码:
1 from math import hypot 2 3 class Vector: 4 def __init__(self,x=0,y=0): 5 self.x = x 6 self.y = y 7 def __repr__(self): #repr() 函数将对象转化为供解释器读取的形式。返回一个对象的 string 格式。 8 return 'Vector(%r %r)' % (self.x,self.y) 9 def __abs__(self): 10 return hypot(self.x,self.y) #hypot()返回欧几里德范数 sqrt(x*x+y*y) 向量的模 11 def __bool__(self): 12 return bool(abs(self)) #模为0 则返False 13 def __add__(self,other): 14 x = self.x+other.x 15 y = self.y+other.y 16 return Vector(x,y) 17 def __mul__(self,scalar): #乘 * 18 return Vector(self.x*scalar,self.y*scalar)
3.字符串表示形式
内置函数repr()能把一个对象用字符串的形式表达出来以便辨认
字符串格式化语法:%和str.format()
%: print("User:%s has completed Action:%s at Time:%s" % (user_name,action_name,current_time)) str.fomat(): print("User:{} has completed Action:{} at Time:{}". format (user_name,action_name,current_time))
str.format 简洁优雅,还可以使用位置索引或关键字索引
"hello,{0}and{1}".format("Chen","Zhang") "hello,{boy}and{girl}!".format(boy="Chen",girl="Zhang")
4.自定义的布尔值
尽管Python里有bool类型,但实际上任何对象都可以用于需要布尔值的上下文中(比如if或while语句,或者and、or和not运算符)
默认情况下,自己定义的类的实例总被认为是真的,除非这个类对__bool__或者__len__函数有自己的实现
5.小结
通过实现特殊方法,自定义数据类型可以表现得跟内置类型一样,从而写出更具Python风格的代码
Python对象的一个基本要求是它得有合理的字符串表示形式,可通过__repr__和__str__来满足要求,前者方便调试和记录日志,后者是给终端用户看的
对序列数据类型的模拟是特殊方法用得最多的地方,Python通过运算符重载这一模式提供了丰富的数值类型