国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python的staticmethod與classmethod實現實例代碼

2020-01-04 15:52:27
字體:
來源:轉載
供稿:網友

本文源于一時好奇,想要弄清出python/279673.html">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類。這個類中有一個__get__函數,當類被“get”的時候,被訪問的時候,會默認把訪問者的instance和class信息都傳進來。所以我們看到不管是否調用method()這個函數,只要碰著了method,這個函數就會觸發,就會打印出當前instance和class信息。雖然ins和Class1的instance各有不同,但__get__函數中只是返回foo函數,所以這里調用method之時就沒有區別,調用的都是同一個function對象。

好的,那么classmethod又如何實現呢?

def foo2(cls, x):  print("foo2's class = ", cls)  print(x)  class ClassMethod(object):  def __init__(self, function):   print("ClassMethod: __init__() called")   self.f = function  def __get__(self, instance, owner = None):   print("/t__get__() called")   print("/tINFO: self = %s, instance =%s, owner = %s" % (self, instance, owner))   def tmpfunc(x):    print("I'm tmpfunc")    return self.f(owner, x)   return tmpfunc  class Class2(object):  method = ClassMethod(foo2)  class Class21(Class2):  pass if __name__ == '__main__':  ins = Class2()  print("ins.method = %s, Class2.method = %s, Class21.method = %s" % (ins.method, Class2.method, Class21.method))  ins.method('abc')  Class2.method('xyz')  Class21.method('asdf') 

輸出結果是:

ClassMethod: __init__() called
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =<__main__.Class2 object at 0xdeb350>, owner = <class '__main__.Class2'>
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =None, owner = <class '__main__.Class2'>
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =None, owner = <class '__main__.Class21'>
ins.method = <function tmpfunc at 0xdee050>, Class2.method = <function tmpfunc at 0xdee1e8>, Class21.method = <function tmpfunc at 0xdee270>
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =<__main__.Class2 object at 0xdeb350>, owner = <class '__main__.Class2'>
I'm tmpfunc
foo2's class = <class '__main__.Class2'>
abc
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =None, owner = <class '__main__.Class2'>
I'm tmpfunc
foo2's class = <class '__main__.Class2'>
xyz
__get__() called
INFO: self = <__main__.ClassMethod object at 0xdeb250>, instance =None, owner = <class '__main__.Class21'>
I'm tmpfunc
foo2's class = <class '__main__.Class21'>
asdf

可以看出,classmethod和staticmethod的實現方法是大同小異。staticmethod比較簡單,直接返回self.f變量就好了,而classmethod不行,需要把調用時候的class類型信息傳給foo2函數,這個函數根據接收的class信息來作不同的工作。(不過我現在也沒有想到可以用來做些什么)

有個地方值得注意,可能同志們剛才也已經想到了,我一定必須要定義一個tempfunc,再返回它才能完成工作嗎?可不可以不要

def tmpfunc(x):    print("I'm tmpfunc")    return self.f(owner, x)   return tmpfunc 

而直接返回一個

return self.f(owner, *args) 

我剛試了一把,直接傳args默認參數是不行的,因為__get__被調用的時候,還沒有把參數傳進來。只有return tmpfunc之后,Class2.method('xyz')的參數才掛在tmpfunc之上。

當然,如果有朋友成功做到了,請一定留言告訴我XD

小結:看來staticmethod和classmethod實現不是很困難,多虧了__get__函數幫忙。前文也提到__get__被調用時會把instance和class信息都填進來,真是幫了很大忙。但是,這個__get__函數到底又是怎么一回事?為什么這么神奇?大家可以參考Python中 __get__和__getattr__和__getattribute__的區別

總結

以上就是本文關于python的staticmethod與classmethod實現實例代碼的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


注:相關教程知識閱讀請移步到python教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 墨江| 环江| 获嘉县| 福海县| 涿州市| 邵武市| 台东县| 文水县| 军事| 林周县| 台南市| 布尔津县| 清丰县| 海原县| 师宗县| 明光市| 常州市| 五华县| 拜城县| 鹤庆县| 黄大仙区| 庆安县| 萨嘎县| 双牌县| 和平县| 东至县| 乌鲁木齐县| 封开县| 正宁县| 靖宇县| 兴山县| 建瓯市| 巩留县| 新田县| 图木舒克市| 道孚县| 石柱| 玉山县| 两当县| 盐源县| 永济市|