形如__xxx__的变量或者函数名,在python中是有特殊用途的,例如__slots__是为了绑定属性的名称,
__len()__方法是为了让class作用于len()函数,很多这样的函数都可以帮忙定制类。
定制类: __str__:帮助返回一个字符串,可以自己设计。__repr__:前面str是返回用户看的结果,
后面这个是返回程序开发者看到的字符串,偷懒处理就可以将str方法赋给repr。
__iter__(): 实现该方法可以返回一个迭代对象,然后python的for循环就会不断调用该迭代对象的
__next__()方法拿到循环的下一个值,直到遇见StopIteration错误退出循环。
__getitem__(): although Fib can use to for..in,but it seems like a list,actually it can't use like a list,
such as get the fifth element.wish it act like list get the element by index,we should use __getitem__():
class Fib(object): def __getitem__(self, n): a, b = 1, 1 for x in range(n): a, b = b, a + b return a
by this way,we can get what want by index:
>>> f = Fib() >>> f[0] 1 >>> f[1] 1 >>> f[2] 2 >>> f[3] 3 >>> f[10] 89 >>> f[100] 573147844013817084101
but list have a magic method:slice,and our Fib() get back a error,the reason is __getitem__() might give
a int,or a slice ,so there should have a judgement:
class Fib(object): def __getitem__(self, n): if isinstance(n, int): # n是索引 a, b = 1, 1 for x in range(n): a, b = b, a + b return a if isinstance(n, slice): # n是切片 start = n.start stop = n.stop if start is None: start = 0 a, b = 1, 1 L = [] for x in range(stop): if x >= start: L.append(a) a, b = b, a + b return L
now we get the function called slice.but there still have so much problems can't be achieve.
__getattr__(): normally,when call a method or attribute of a class, if it doesn't exist, it will
be reported wrong.系统会提示我们要找到这个方法或这属性才行,但python()有一个__getattr__()
方法,动态返回一个属性:
class Student(object): def __init__(self): self.name = 'Michael' def __getattr__(self, attr): if attr=='score': return 99 >>> s = Student() >>> s.name 'Michael' >>> s.score 99
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用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('Michael') >>> s() # self参数不要传入 My name is Michael.
那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable
对象,比如函数和我们上面定义的带有__call__()
的类实例:
>>> callable(Student()) True >>> callable(max) True >>> callable([1, 2, 3]) False >>> callable(None) False >>> callable('str') False
使用枚举类: 导入enum的Enum可以把一组相关常量定义在一个class,且class不可变,而且成员可以直接比较:
from enum import Enum Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) from enum import Enum, unique @unique class Weekday(Enum): Sun = 0 # Sun的value被设定为0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6