# 绑定属性的时候,虽然方便,但是直接暴露出来,没法检查参数还可以随便改
# 通过set_score,get_score可以检查参数
class student(object):
def get_score(self):
return self.__score
def set_score(self,value):
if not isinstance(value,int):
raise ValueError('score must be integer!')
if value >100 or value < 0:
raise ValueError('score must between 0-100')
self.__score = value
s = student()
s.set_score(10)
s.get_score()
>>> 10
python复制代码
# 现在觉得太麻烦了 可以用装饰器给函数动态加上功能 @property负责把一个方法变成属性调用
class student(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
s = student()
s.score = 60 # 转化为了s.set_score(60)
s.score # 转化为了s.get_score
>>> 60
3.多重继承
python复制代码
# 子类通过继承多种父类,同时获得多个父类的功能
class Animal(object):
pass
class Mammal(Animal):
pass
class Bird(Animal):
pass
class Dog(Mammal):
pass
class Bat(Mammal):
pass
class Parrot(Bird):
pass
class Ostrich(Bird):
pass
python复制代码
# 给动物加上功能,可以通过继承功能类
class Runnable(object):
def run(self):
print('running...')
class Flyable(object):
def fly(self):
print('flying...')
class Dog(Mammal,Runnable):
pass
class Bat(Mammal,Flyable):
pass
# 通过这样多重继承的方式,一个子类可以获得多个父类的功能
python复制代码
# MixIn
# 为了更好看出继承关系,Runnable和Flyable改为RunnableMixIn和FlyableMixIn
class Dog(Mammal,RunnableMixIn):
pass
4.定制类
4.1 str
4.2 iter
4.3 getitem
4.4 getattr
4.5 call
python复制代码
# 4.1 __str__
# 先打印一个实例
class student(object):
def __init__(self,name):
self.name = name
print(student('sb'))
# 打印出来不好看
>>> <__main__.student object at 0x1077bba20>
# 不用print的时候,打印出来的实例还是不好看
s = student('sb')
s
>>> <__main__.student at 0x1078d6630>
python复制代码
# 因为直接显示变量调用的不是__str__(),而是__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('sb')
s
>>> student object (name=sb)
python复制代码
# __iter__
# 想要被for循环迭代,这个类就要有__iter__(),返回一个迭代对象,for就会不断调用该调用这个迭代对象的__next__()方法拿到下一个值,直到StopIteration退出循环
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 > 5:
raise StopIteration
return self.a
for n in Fib():
print(n)
>>> 1
>>> 1
>>> 2
>>> 3
>>> 5
python复制代码
# __getitem__
# 虽然可以用for循环了,但是想要像list一样切片
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
f = Fib()
f[0]
>>> 1
f[1:3]
>>> [1, 2]
python复制代码
# 4.4 __getattr__
# 当没有定义某些属性的时候,通过__getattr__,动态返回一个属性
class student(object):
def __getattr__(self,attr):
if attr == 'age':
return lambda:22
raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
s = student()
s.age()
>>> 22
python复制代码
# 4.5 __call__ 对实例本身进行调用
class student(object):
def __init__(self,name):
self.name = name
def __call__(self):
print('Your name is %s'%self.name)
s = student('aa')
s()
>>> Your name is aa