Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。
比如:
__str__ 与__repr__
__iter__
__getitem__
__call__
__str__ 与__repr__
class Student(object): def __init__(self,name): self.name = name ''' 只有以上的话, print(Student('kumata')) 输出结果:<__main__.Student object at 0x109afb190> ''' def __str__(self): return 'student object (name:%s)' % self.name ''' print(Student('kumata')) #student object (name:kumata) 但是直接 s = (Student('kumata'))然后敲输出s 还是:<__main__.Student object at 0x109afb310> 这是因为直接显示变量调用的不是__str__(),而是__repr__(), 两者的区别是__str__()返回用户看到的字符串, 而__repr__()返回程序开发者看到的字符串, 也就是说,__repr__()是为调试服务的。 解决办法是再定义一个__repr__()。 但是通常__str__()和__repr__()代码都是一样的, 所以,有个偷懒的写法: ''' __repr__ = __str__
__iter__
如果一个类想被用于for ... in
循环,类似list或tuple那样,就必须实现一个__iter__()
方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()
方法拿到循环的下一个值,直到遇到StopIteration
错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:
class Fib(object): def __init__(self): self.a, self.b = 0, 1 # 初始化两个计数器a,b def __iter__(self): return self # 实例本身就是迭代对象,故返回自己 def __next__(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 100000: # 退出循环的条件 raise StopIteration() return self.a # 返回下一个值 for i in Fib(): print(i) #输出结果 1 1 2 3 5 ... 46368 75025
__getitem__
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如:Fib()[5]会抛出错误
要表现得像list那样按照下标取出元素,需要实现__getitem__()
方法:
class Fib(object): def __getitem__(self, n): a, b = 1, 1 for x in range(n): a, b = b, a + b return a #访问 >>> f = Fib() >>> f[0] 1 >>> f[1] 1 >>> f[2] 2 >>> f[3] 3 >>> f[10] 89 >>> f[100] 573147844013817084101
__call__
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()
来调用。能不能直接在实例本身上调用呢?在Python中答案是肯定的。
任何类,只需要定义一个__call__()
方法,就可以直接对实例进行调用。
class Student(object): def __init__(self, name): self.name = name def __call__(self): print('My name is %s.' % self.name) #调用方式如下: >>> s = Student('kumatal') >>> s() # self参数不要传入 My name is kumata.