本文源于一時好奇,想要弄清出python的staticmethod()這一builtin方法的實現,查了一些資料(主要是python官方手冊了)匯集于此
python在類中,有三種調用method的方法:普通method,staticmethod和classmethod
前兩個應該都好理解,classmethod就是在調用這個函數的時候,會把調用對象的class object對象隱式地傳進去。咦?這個class object不是一個類型?No,在python里面,class object不像靜態語言一樣是個類型,它在虛擬機中,就是一個對象。普通method調用需要把自己self作為參數傳遞,初學的時候怎么著也不能理解,不過看多了就自然熟悉了。比較奇怪的是staticmethod和classmethod不像靜態語言一樣,通過保留關鍵字定義,而是使用@staticmethod或者staticmethod()這種builtin函數進行定義。這個@staticmethod到底是個什么東東?
@staticmethod def foo(x): print(x)
之前用過java,所以第一反應這是個annotation……唔,確實感覺像個AOP的東西,python里把它稱作decorator。如果我們要自己實現一個staticmethod,該怎么寫呢?
研究了下官方的代碼,我再改了改,感覺應該這樣寫:
def foo(x): print(x) class StaticMethod(object): def __init__(self, function): print("__init__() called") self.f = function def __get__(self, instance, owner): print("/t__get__() called") print("/tINFO: self = %s, instance =%s, owner = %s" % (self, instance, owner)) return self.f class Class1(object): method = StaticMethod(foo) if __name__ == '__main__': ins = Class1() print("ins = %s, Class1 = %s" % (ins, Class1)) print("ins.method = %s, Class1.method = %s" % (ins.method, Class1.method)) ins.method('abc') Class1.method('xyz') 輸出結果是:
__init__() called
ins = <__main__.Class1 object at 0xece2d0>, Class1 = <class '__main__.Class1'>
__get__() called
INFO: self = <__main__.StaticMethod object at 0xece5d0>, instance =<__main__.Class1 object at 0xece2d0>, owner = <class '__main__.Class1'>
__get__() called
INFO: self = <__main__.StaticMethod object at 0xece5d0>, instance =None, owner = <class '__main__.Class1'>
ins.method = <function foo at 0xeb6c00>, Class1.method = <function foo at 0xeb6c00>
__get__() called
INFO: self = <__main__.StaticMethod object at 0xece5d0>, instance =<__main__.Class1 object at 0xece2d0>, owner = <class '__main__.Class1'>
abc
__get__() called
INFO: self = <__main__.StaticMethod object at 0xece5d0>, instance =None, owner = <class '__main__.Class1'>
xyz
嗯,看上去一切都挺順利,Class1包含了一個變量method,不過這個method其實也是一個特殊處理過的StaticMethod類。這個類中有一個
新聞熱點
疑難解答