python中实现定制类的特殊方法总结
看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。
__slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数。
除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。
__str__
我们先定义一个Student类,打印一个实例:
>>>classStudent(object): ... def__init__(self,name): ... self.name=name ... >>>printStudent('Michael') <__main__.Studentobjectat0x109afb190>
打印出一堆<__main__.Studentobjectat0x109afb190>,不好看。
怎么才能打印得好看呢?只需要定义好__str__()方法,返回一个好看的字符串就可以了:
>>>classStudent(object): ... def__init__(self,name): ... self.name=name ... def__str__(self): ... return'Studentobject(name:%s)'%self.name ... >>>printStudent('Michael') Studentobject(name:Michael)
这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。
但是细心的朋友会发现直接敲变量不用print,打印出来的实例还是不好看:
>>>s=Student('Michael') >>>s <__main__.Studentobjectat0x109afb310>
这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
解决办法是再定义一个__repr__()。但是通常__str__()和__repr__()代码都是一样的,所以,有个偷懒的写法:
classStudent(object): def__init__(self,name): self.name=name def__str__(self): return'Studentobject(name=%s)'%self.name __repr__=__str__
__iter__
如果一个类想被用于for...in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:
classFib(object): def__init__(self): self.a,self.b=0,1#初始化两个计数器a,b
def__iter__(self): returnself#实例本身就是迭代对象,故返回自己
defnext(self): self.a,self.b=self.b,self.a+self.b#计算下一个值 ifself.a>100000:#退出循环的条件 raiseStopIteration(); returnself.a#返回下一个值