[TOC]
装饰器
python中的装饰器(decorator)是在pep 318中被首次引入,它的本质是一个函数这个函数是接受其它参数为参数,并且用一个新的,修改后的函数作为替换,最常见的装饰器就classmethod和staticmethod
def happy(f):
return lambda x:2*x
@happy
def haha(x):
print "you can't see me"
return 12*x
print haha(1)
方法
方法是作为类属性的函数
如果直接调用类方法,py2里会提示是一个未绑定的方法,py3里会提示这是一个函数
class happy():
name = 'happy'
def hh(self,ddd):
return ddd
print happy.hh('aaa')
python3里,可以传入一个实例化的class进去,调用未绑定的方法
class happy():
name = 'happy'
def hh(self,ddd):
return ddd
print(happy.hh(happy(),'aaa'))
静态方法 staticmethod
除了python3里传未绑定的类给类方法之外,还有个办法可以调用未绑定的类方法
就是静态方法
class happy():
name = 'happy'
@staticmethod
def hh():
return 111
print happy.hh()
静态方法就是定义类方法时候加一个staticclass的decorator,它有几个好处
调用方法前,不必实例化方法,减少开销
提高代码可读性
可以在子类中覆盖静态方法
类方法 classmethod
classmethod是直接绑定到类的方法
类方法最有用的是创建工厂方法,也就是以特定方式实例化对象
类方法定义时候,总是要绑定到它附着的类上,而且它的第一个参数必须是类本身,比如
class happy():
name = 'happy'
@classmethod
def hh(cls):
return 111
print happy.hh()
抽象方法 abstactclass和abc
抽象方法是在基类里定义的,但是需要子类继续完善的方法
好多语言里,抽象方法只能定义,不能实现,py里抽象方法是可以实现一些通用功能,并且,通过super,在子类里被调用
如果不用abc,类被继承,但是抽象方法没重新实现的时候,抽象方法不被调用就不会报错
解决方案就是用abc,示例如下
import abc
class happy():
__metaclass__ = abc.ABCMeta
name = 'happy'
@staticmethod
@abc.abstractmethod
def hh(ddd):
return ddd.name + 'static'
print happy.hh('aaa')
混合使用三种方法
静态方法或者类方法可以和抽象方法混用
如果混用了,抽象方法在子类里,无须实例化,即可调用
示例如下
import abc
class happy():
__metaclass__ = abc.ABCMeta
name = 'happy'
@staticmethod
@abc.abstractmethod
def hh(ddd):
return ddd + 'static'
class haha(happy):
def aa(self):
return super(haha,self).name
print haha().hh('dd')
super
python比较牛逼的地方是支持mixin和多重继承,可以很方便的通过super函数,调用一个类的父类,那么问题来了,如果一个方法,再多个父类里都有,那么调用那个父类呢?这就涉及一个mro的算法,mro变换过多次,最近的一次是py2.3里实现的c3算法,C3算法解决了单调性问题和只能继承无法重写问题
python里的super算法,总体可以归结成一句话,自上到下,自左到右
把左边的类,从上到下遍历过了,才会遍历
就像下面的图,遍历顺序是a b d c e f
c3算法更具体解释可以参见官网
class D(object):
pass
class E(object):
pass
class F(object):
pass
class C(E, F):
pass
class B(D,E):
pass
class A(B, C):
pass
if __name__ == '__main__':
print A.__mro__
6
---
Level 3 | O | (more general)
/ --- \
/ | \ |
/ | \ |
/ | \ |
--- --- --- |
Level 2 3 | D | 4| E | | F | 5 |
--- --- --- |
\ \ _ / | |
\ / \ _ | |
\ / \ | |
--- --- |
Level 1 1 | B | | C | 2 |
--- --- |
\ / |
\ / \ /
---
Level 0 0 | A | (more specialized)
---