__slots__
限制类的绑定属性
__str__
: print打印对象,返回用户看到的字符串
__repr__
:返回程序开发者看到的字符串,如直接输入变量,是为调试服务的
1 | class Student(object): |
可以直接:
1 | __repr = __str__ |
__iter__
: 一个类用于for…in循环
1 | class Fib(object): |
__getitem__
:Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
1 | >>> Fib()[5] |
要表现得像list那样按照下标取出元素,需要实现getitem()方法:
1 | class Fib(object): |
但是list有个神奇的切片方法:
1 | >>> list(range(100))[5:10] |
对于Fib却报错,原因是getitem()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断
1 | def __getitem__(self, n): |
但是现在没有对step参数处理f[:10:2],也没有对负数做处理 此外,如果把对象看成dict,getitem()的参数也可能是一个可以作key的object,例如str。 与之对应的是setitem()方法,把对象视作list或dict来对集合赋值。最后,还有一个delitem()方法,用于删除某个元素。 总之,通过上面的方法,我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。
__getattr__
:动态返回一个属性。
1 | class Student(object): |
当调用不存在的属性时,比如score,Python解释器会试图调用getattr(self, ‘score’)来尝试获得属性,这样,我们就有机会返回score的值: 注意,只有在没有找到属性的情况下,才调用getattr,已有的属性,比如name,不会在getattr中查找
__call__
:一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?在Python中,答案是肯定的。
任何类,只需要定义一个call()方法,就可以直接对实例进行调用。请看示例
1 | class Student(object): |
调用方式如下:
1 | >>> s = Student('Michael') |
__call__()
还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。
怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有call()的类实例:
1 | >>> callable(Student()) |
枚举类
1 | from enum import Enum |
value属性则是自动赋给成员的int常量,默认从1开始计数。 如果需要更精确地控制枚举类型,可以从Enum派生出自定义类:
1 | from enum import Enum, unique |
@unique装饰器可以帮助我们检查保证没有重复值。
访问这些枚举类型可以有若干种方法:
1 | >>> day1 = Weekday.Mon |