OOP高级编程

给类绑定属性和方法

#绑定属性
>>> class Student(object):
...     pass
...
>>> #绑定属性
...
>>> Student.classname='student class'
>>> s = Student()
>>> s.classname
'student class'
>>> s2 = Student()
>>> s2.classname
'student class'
>>> s2.myownattr=100
>>> print s2.myownattr
100
>>> print s.myownattr
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'Student' object has no attribute 'myownattr'

绑定方法

#给类实例绑定方法
>>> class Student(object):
...     pass
...
>>> def set_age(self, age):
...     self.age = age

>>> s = Student()

>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法,其他实例不共享
>>> print s.age
10

#给类绑定方法
>>> Student.set_age = MethodType(set_age, None, Student)
>>> s2 = Student()
>>> s2.set_age(100)
>>> print s2.age
100

通过slots变量,来限制该class能添加的属性;

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

slots定义的属性仅对当前类起作用,对继承的子类是不起作用的

@property

Python内置的@property装饰器就是负责把一个方法变成属性调用的.

#!/usr/bin/env python
# _*_ encoding: utf-8 _*_

import datetime
class Studen(object):

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

    @birth.setter
    def birth(self, value):
        if value <= 0:
            raise ValueError('value must much than 0!')
        self._birth = value

    @property
    def age(self):   #age只读
        return  datetime.datetime.now().year - self._birth


if __name__ == '__main__':
    s1 = Studen()
    #s1.birth = -2013   #valueError
    s1.birth = 2013
    print s1.birth
    print s1.age

输出:
2013
5

多重继承

#示例
class Dog(Mammal, Runnable):
    pass

多重继承时,可同时继承多个类,获取其中的属性及方法,Python中将此种方法称为mixin模式

__xxx__

slots :用于限制类成员
len() : 作用于len函数
str() : 作用于print函数
repr(): 同str(),为调试服务
iter():迭代对象,for循环会不断调用next()方法,拿到循环下一个值,直到StopIteration异常时退出循环;

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 # 返回下一个值

调用:
>>> for n in Fib():
...     print n
...
1
1
2

getitem() : 通过下标访问及切片

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

setitem()如getitem类似,功能相反

getattr当调用类的方法或属性时,如果不存在,就会报错。

class Student(object):
    def __init__(self):
        self.name = 'Michael'

s=Student()
print s.name    # ok
print s.score    # exception 

#new demo
class Student(object):

    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):
        if attr=='score':
            return 99

#当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值

call 直接对实例进行调用

class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)

>>> s = Student('Michael')
>>> s()
My name is Michael.

你可能感兴趣的:(OOP高级编程)