python 面向对象的动态语言

1. 给实例绑定任何属性和方法

>>> class Student(object):
...  pass
... 
>>> s = Student()
>>> s.name
Traceback (most recent call last):
  File "", line 1, in 
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)

>>> s.set_age = meth
>>> s.set_age(25)
>>> s.age
25
>>> 
// 注意下面s2找不到name属性,说明属性和方法都是给s这个实例添加的
>>> s2 = Student()
>>> s2.name
Traceback (most recent call last):
  File "", line 1, in 
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 "", line 1, in 
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...')

你可能感兴趣的:(python 面向对象的动态语言)