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