__slots__:
Python是动态语言 ,于是当我们定义了一个class之后 创建一个class的实例后 我们可以给改实例绑定任何属性和方法
>>> class Student(object):
pass
>>>s=Student()
>>>s.name='lc'#动态给实例绑定一个属性
>>>print s.name
lc
同样还可以给一个实例绑定一个方法
>>> def set_age(self,age):
self.age=age
>>>from types import MethodType
>>>s.set_age=MethodType(set_age,s,Student)
>>>s.set_age(25)
>>>s.age
25
但是这样绑定 在另一个实例上是不起作用的 因此需要将其绑定在 Student上
>>> def set_score(self,score):
self.score=score
>>>Student.set_score=MethondType(set_score,None,Student)
__slots__ :
变量 这个变量用来限制这个class能够添加的属性。
>>> class Student(object):
__slots__=('name','age')
这样除了name和age 这两个属性外 不能再绑定其他的属性 ,但是需要注意的是 __slots__这个变量只对当前的类起作用 不对子类起作用
@property
相当于装饰器 负责把一个方法变成属性调用。
>>> class Student(object):
@property
def score(self):
return self.score
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueError('must be a integer')
if value<0 or value>100:
raise ValueError('0-100')
self.score=value
>>> s=Student()
>>> s.score=60 #OK
>>> s.score
60
>>>s.score=9999
Traceback........
ValueRrror:0-100
@property 把一个getter方法变成属性 然后又创建了@score.setter 负责把一个setter方法变成属性赋值 如果没有@score.setter 方法 则这个属性就是只读的属性
__iter__().
如果想要被for...in循环遍历 就必须实现 __iter__()这个方法 该方法返回一个迭代对象 Python for 循环就会不断调用迭代对象的next()方法拿到下一个值 直到遇到StopIteration 异常
>>> class Fib(objcet):
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
.......
__getitem__:
上述实例 Fib 虽然能过用于for...in 循环 但是却没有办法像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[3]
3
但是这样 对于 切片却不可用 原因是 切片传入的是切片对象 slice
>>> class Fib(object):
def __getitem__(self,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):
start=n.start
stop=n.stop
a,b=1,1
L=[]
for x in range(stop):
if x>=start:
L.append(a)
a,b=b,a+b
return L
>>> f=Fib()
>>> f[0:5]
[1,1,2,3,5]
这样就实现了切片 但是没有对step的处理 也没有负数的处理
__getattr__().
本来如果调用了对象不存在的属性就会报错 但是 写上 __getattr__()之后 解释器就会尝试从这个方法中获得属性的值
>>> class Student(object):
def __init__(self):
self.name='lc'
def __getattr()__(self,attr):
if attr=='score':
return 99
raise AttributeErrors('has no this attr')
>>> s = Student()
>>> s.score
99
__call__() :
让对象本身相当于一个方法一样被调用
>>> class Student(object):
def __init__(self,name):
self.name=name
def __call__(self):
print self.name
>>> s=Student('lc')
>>> s()
lc
__call()__还可以定义参数 这样就可以把对象像一个函数一样调用 Callable() 函数可以判断一个对象是否可以被调用。