1. 给实例绑定任何属性和方法
>>> class Student(object):
... pass
...
>>> s = Student()
>>> s.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'name'
>>> s.name = 'micheal'
>>> s.name
'micheal'
>>> def set_age(self,age):
... self.age = age
...
>>> from types import MethodType
>>> meth = MethodType(set_age,s)
>>> type(meth)
<class 'method'>
>>> s.set_age = meth
>>> s.set_age(25)
>>> s.age
25
>>>
// 注意下面s2找不到name属性,说明属性和方法都是给s这个实例添加的
>>> s2 = Student()
>>> s2.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'name'
>>> s.name
'micheal'
>>>
// 因此,为了给所有实例都绑定方法,可以给class绑定方法:
>>> def set_score(self,score):
... self.score = score
...
>>> Student.set_score = set_score
>>> s.set_score(25)
>>> s2
<__main__.Student object at 0x106d9cd00>
>>> s2.set_score(26)
>>> s.score
25
>>> s2.score
26
>>>
2. 但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
3. @property装饰器的使用
# 把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值
# 只定义getter方法,不定义setter方法就是一个只读属性
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 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
...
ValueError: score must between 0 ~ 100!
# 使用例子:
class Student(object):
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
@property
def age(self):
return 2015 - self._birth
# ✨✨✨✨✨:如果不实现@xxx.setter 是不会创建一个名为_xxx的属性的
4. python支持多重继承:这种设计通常称之为MixIn(只允许单一继承的语言(如Java)不能使用MixIn的设计。)
class Animal(object):
pass
class Runnable(object):
def run(self):
print('Running...')
class Flyable(object):
def fly(self):
print('Flying...')
# 多重继承:这种设计通常称之为MixIn。
class Dog(Mammal, Runnable):
pass
# 所以规范点:
class RunnableMixIn(object):
def run(self):
print('Running...')
class FlyableMixIn(object):
def fly(self):
print('Flying...')
网友评论