Python定制类
#最近再根据廖雪峰老师的python学习教程学习,以下是学习过程中做的一些学习总结
定制类
在python中,类似__xxx__的变量都属于特殊变量,可以帮助我们定制类。
__iter__
如果想要一个类被用于for...in...循环,类似于list或者tuple那样就用到了__iter__方法,这个特殊变量返回一个迭代对象,python使用该方法时就会不断调用该方法,并且利用__next__()方法循环下一个值:
class Fib(object): def __init__(self): self.a ,self.b = 0,1 def __iter__(self): return self def __next__(self): self.a ,self.b = self.b ,self.a+self.b if self.a > 100: return raise StopIteration() return self.a
然后我们使用for...in..循环来看下结果:
>>> for x in Fib(): print(x) 1 1 2 3 5 8 13 21 34 55 89
__getitem__
Fib虽然能用于for循环,看起来和list很像,但是并不能当作list来使用,例如:
>>> Fib()[5] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Fib' object does not support indexing
如果想要class可以像list那样使用则需要__getitem__方法:
class Fbi(object): def __getitem__(self,n): self.n = n a,b = 0,1 for x in range(n): a,b = b,a+b return a
我们就可以访问获取数列的值:
>>> a = Fbi() >>> a[5] 8 >>> a[1] 1 >>> a[10] 89
但是list有一个切片方法,而__getitem__会报错,原因是__getitem__传入的参数可能是个int,也可能是个slice,所以需要进行判断:
class Fbi(object): def __getitem__(self,n): if isinstance(n,int): a,b = 0,1 for x in range(n): a,b = b,a+b return a if isinstance(n,slice): start = n.start stop = n.stop if start == None: start = 0 a,b =0,1 L =[] for x in range(stop): if x >= start: L.append(a) a,b=b,a+b return L
这样我们就可以进行切片操作:
>>> a = Fbi() >>> a[0:5] [0, 1, 1, 2, 3]
__getattr__
在python类中,我们会绑定属性,但是如果我们访问不存在的属性时则会报错,这个时候可以用到__getattr__方法
__getattr__方法会给class设定一个动态属性,如果class中不存在该属性时,则会调用动态属性。
class Fbi(object): def __init__(self,name): self.name = 'Bob' def __getattr__(self,attr): if attr = 'score': return 0
当调用不存在的score属性时就会调用动态属性:
>>>a = Fbi() >>>a.score 0
只有当__init__中没有属性时才会调用动态属性,如果绑定属性存在的化,则不会调用。
__call__
在python中存在调用实例的方法__call__,只要定义call()方法,我们就可以在类中调用实例本身:
class Student(objecct): def __init__(self,name): self.name = name def __call__(self): print('My name is %s' % self.name)
调用实例:
>>>a = Student('Bob') >>>a() My name is Bob
call还可以定义参数。并且判断一个变量是对象还是函数,可以被调用就是callable对象:
>>> callable(Student()) True >>> callable(max) True >>> callable([1, 2, 3]) False >>> callable(None) False >>> callable('str') False
通过callable()
函数,我们就可以判断一个对象是否是“可调用”对象。