定制类
__slots__ 说明
为了限制类的实例属性,比如只对Student实例添加name和age属性
为了达到这个目的,python允许在定义class的时候,定义一个特殊的 __slots__ 变量,来限制该class实例能添加的属性:
class Student(object):
__slots__ = ('name', 'age') #用tuple定义允许绑定的属性名称
使用 __slots__ 要注意,__slots__定义的属性仅对当前实例起作用,对继承的子类是不起作用的
__str__ 、 __repr__说明
这两个方法是针对类中字符串进行处理的
#
class Student(object):
def __init__(self, name):
self.name = name
>> print(Student('wynter'))
>> <__main__.Student object at 0x0000000004F81630>
# 定义一个__str__()方法
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name %s)' % self.name
>> print(Student('wynter'))
... Student object (name: wynter) # 打印的字符串被代替
>> s = Student('wynter')
>> s
... <__main__.Student at 0x4f81b00> # 这样还是不好看
# 定义一个__repr__()方法
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name %s)' % self.name
__repr__ = __str__
>> s = Student('wynter')
>> s
... Student object (name: wynter) # 这样就好看多了
直接显示变量调用的是__repr__(), 两者的区别是__str__()返回用户看到的字符串,而__repr__()返回开发者看到的字符串,也就是说,后者是为调试服务的
__iter__说明
如果一个类想用于被for … in循环,类似list或者tuple,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopInteration错误时退出循环
>>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 > 10000:
raise StopIteration()
return self.a
>> for n in Fib():
print(n)
...
1
1
2
3
5
8
...
__getitem__说明
该方法可将类实例化对象的迭代或者循环当成list处理
class Fib(object):
def __getitem__(self, n):
a, b = 0, 1
for x in range(n):
a, b = b , a + b
return a
>> f = Fib()
>> f[0]
1
>> f[1]
1
>> f[10]
89
因为getitem()传入的参数可能是一个int,也可能是一个切片对象,所以要做判断
class Fib(object):
def __getitem__(self, n): # n是索引
if isinstance(n, int):
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
__getattr__说明
调用__getattr__()方法,可以动态返回一个属性
class Student(object):
def __init__(self):
self.name = 'wynter'
def __getattr__(self, attr):
if attr == 'score':
return 99
__call__说明
任何类,只需定义一个call()方法,就可以直接对实例进行调用
class Student(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('My name is %s.' % self.name)
>> s = Student('wynter')
>> s()
My name is wynter