再一次重新学习Python——面向对象高级编程

给实例绑定一个方法:

>>> 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

为了给所有实例都绑定方法,可以给class绑定方法:

>>> def set_score(self, score):
...     self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student)
  •  使用__slots__

用来限制class可以添加的属性

>>> class Student(object):
...     __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
...

 使用__slots__要注意,它定义的属性只对当前类起作用,对继承的子类是不起作用的。

除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__。

  • 使用@property

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


'''
@property
def birth(self):
    return self._birth

@birth.setter
def birth(self, value):
    self._birth = value

'''

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

>>> 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 Dog(Mammal, Runnable):
    pass

Mixin模式

目的是给一个类增加多个功能,在设计类的时候,优先考虑通过多重继承来组合多个Mixin的功能。

__str__()返回一个好看的字符串————改变的是print输出变量

__repr__()改变的事直接显示变量调用,为调试服务

__iter__

如果一个类想被用于for...in循环,类似list或者tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:

class Fib(object):
    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 # 返回下一个值

现在,试试把Fib实例作用于for循环:

>>> for n in Fib():
...     print n
...
1
1
2
3
5
...
46368
75025

更多定制类翻看博客

  • 使用元类

type()和metaclass(元类)

先定义metaclass,就可以创建类,最后创建实例。metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。

猜你喜欢

转载自blog.csdn.net/Saikikky/article/details/81163181