精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

為什么 Classmethod 比 Staticmethod 更受寵?

開發 前端
我們知道,classmethod 和 staticmethod 都可以作為函數的裝飾器,都可用于不涉及類的成員變量的方法,但是你查一下 Python 標準庫就會知道 classmethod 使用的次數(1052)要遠遠多于 staticmethod(539),這是為什么呢?

[[442137]]

 我們知道,classmethod 和 staticmethod 都可以作為函數的裝飾器,都可用于不涉及類的成員變量的方法,但是你查一下 Python 標準庫就會知道 classmethod 使用的次數(1052)要遠遠多于 staticmethod(539),這是為什么呢?

這就要從 staticmethod 和 classmethod 的區別說起。

1、從調用形式上看,二者用法差不多

先說下什么是類,什么是實例,比如說 a = A(),那么 A 就是類,a 就是實例。

從定義形式上看,clasmethod 的第一個參數是 cls,代表類本身,普通方法的第一個參數是 self,代表實例本身,staticmethod 的參數和普通函數沒有區別。

從調用形式上看,staticmethod 和 classmethod 都支持類直接調用和實例調用。

  1. class MyClass: 
  2.     def method(self): 
  3.         ""
  4.         Instance methods need a class instance and 
  5.         can access the instance through `self`. 
  6.         ""
  7.         return 'instance method called', self 
  8.  
  9.     @classmethod 
  10.     def classmethod(cls): 
  11.         ""
  12.         Class methods don't need a class instance. 
  13.         They can't access the instance (self) but 
  14.         they have access to the class itself via `cls`. 
  15.         ""
  16.         return 'class method called', cls 
  17.  
  18.     @staticmethod 
  19.     def staticmethod(): 
  20.         ""
  21.         Static methods don't have access to `cls` or `self`. 
  22.         They work like regular functions but belong to 
  23.         the class's namespace. 
  24.         ""
  25.         return 'static method called' 
  26.  
  27. All methods types can be 
  28. # called on a class instance: 
  29. >>> obj = MyClass() 
  30. >>> obj.method() 
  31. ('instance method called', <MyClass instance at 0x1019381b8>) 
  32. >>> obj.classmethod() 
  33. ('class method called', <class MyClass at 0x101a2f4c8>) 
  34. >>> obj.staticmethod() 
  35. 'static method called' 
  36.  
  37. # Calling instance methods fails 
  38. # if we only have the class object: 
  39. >>> MyClass.classmethod() 
  40. ('class method called', <class MyClass at 0x101a2f4c8>) 
  41. >>> MyClass.staticmethod() 
  42. 'static method called' 

2、先說說 staticmethod。

如果一個類的函數上面加上了 staticmethod,通常就表示這個函數的計算不涉及類的變量,不需要類的實例化就可以使用,也就是說該函數和這個類的關系不是很近,換句話說,使用 staticmethod 裝飾的函數,也可以定義在類的外面。我有時候會糾結到底放在類里面使用 staticmethod,還是放在 utils.py 中單獨寫一個函數?比如下面的 Calendar 類:

  1. class Calendar: 
  2.     def __init__(self): 
  3.         self.events = [] 
  4.  
  5.     def add_event(self, event): 
  6.         self.events.append(event) 
  7.  
  8.     @staticmethod 
  9.     def is_weekend(dt:datetime): 
  10.         return dt.weekday() > 4 
  11.  
  12. if __name__ == '__main__'
  13.     print(Calendar.is_weekend(datetime(2021,12,27))) 
  14.     #outputFalse 

里面的函數 is_weekend 用來判斷某一天是否是周末,就可以定義在 Calendar 的外面作為公共方法,這樣在使用該函數時就不需要再加上 Calendar 這個類名。

但是有些情況最好定義在類的里面,那就是這個函數離開了類的上下文,就不知道該怎么調用了,比如說下面這個類,用來判斷矩陣是否可以相乘,更易讀的調用形式是 Matrix.can_multiply:

  1. from dataclasses import dataclass 
  2. @dataclass 
  3. class Matrix: 
  4.     shape: tuple[intint] # python3.9 之后支持這種類型聲明的寫法 
  5.  
  6.     @staticmethod 
  7.     def can_multiply(a, b): 
  8.         n, m = a.shape 
  9.         k, l = b.shape 
  10.         return m == k 

3、再說說 classmethod。

首先我們從 clasmethod 的形式上來理解,它的第一個參數是 cls,代表類本身,也就是說,我們可以在 classmethod 函數里面調用類的構造函數 cls(),從而生成一個新的實例。從這一點,可以推斷出它的使用場景:

當我們需要再次調用構造函數時,也就是創建新的實例對象時

需要不修改現有實例的情況下返回一個新的實例

比如下面的代碼:

  1. class Stream: 
  2.  
  3.     def extend(self, other): 
  4.         # modify self using other 
  5.         ... 
  6.  
  7.     @classmethod 
  8.     def from_file(cls, file): 
  9.         ... 
  10.  
  11.     @classmethod 
  12.     def concatenate(cls, *streams): 
  13.         s = cls() 
  14.         for stream in streams: 
  15.             s.extend(stream) 
  16.         return s 
  17.  
  18. steam = Steam() 

當我們調用 steam.extend 函數時候會修改 steam 本身,而調用 concatenate 時會返回一個新的實例對象,而不會修改 steam 本身。

4、本質區別

我們可以嘗試自己實現一下 classmethod 和 staticmethod 這兩個裝飾器,來看看他們的本質區別:

  1. class StaticMethod: 
  2.     def __init__(self, func): 
  3.         self.func = func 
  4.  
  5.     def __get__(self, instance, owner): 
  6.         return self.func 
  7.  
  8.     def __call__(self, *args, **kwargs):  # New in Python 3.10 
  9.         return self.func(*args, **kwargs) 
  10.  
  11.  
  12. class ClassMethod: 
  13.     def __init__(self, func): 
  14.         self.func = func 
  15.  
  16.     def __get__(self, instance, owner): 
  17.         return self.func.__get__(owner, type(owner)) 
  18.  
  19. class A: 
  20.     def normal(self, *args, **kwargs): 
  21.         print(f"normal({self=}, {args=}, {kwargs=})"
  22.  
  23.     @staticmethod 
  24.     def f1(*args, **kwargs): 
  25.         print(f"f1({args=}, {kwargs=})"
  26.  
  27.     @StaticMethod 
  28.     def f2(*args, **kwargs): 
  29.         print(f"f2({args=}, {kwargs=})"
  30.  
  31.     @classmethod 
  32.     def g1(cls, *args, **kwargs): 
  33.         print(f"g1({cls=}, {args=}, {kwargs=})"
  34.  
  35.     @ClassMethod 
  36.     def g2(cls, *args, **kwargs): 
  37.         print(f"g2({cls=}, {args=}, {kwargs=})"
  38.  
  39.  
  40. def staticmethod_example(): 
  41.     A.f1() 
  42.     A.f2() 
  43.  
  44.     A().f1() 
  45.     A().f2() 
  46.  
  47.     print(f'{A.f1=}'
  48.     print(f'{A.f2=}'
  49.  
  50.     print(A().f1) 
  51.     print(A().f2) 
  52.  
  53.     print(f'{type(A.f1)=}'
  54.     print(f'{type(A.f2)=}'
  55.  
  56.  
  57. def main(): 
  58.     A.f1() 
  59.     A.f2() 
  60.  
  61.     A().f1() 
  62.     A().f2() 
  63.  
  64.     A.g1() 
  65.     A.g2() 
  66.  
  67.     A().g1() 
  68.     A().g2() 
  69.  
  70.     print(f'{A.f1=}'
  71.     print(f'{A.f2=}'
  72.  
  73.     print(f'{A().f1=}'
  74.     print(f'{A().f2=}'
  75.  
  76.     print(f'{type(A.f1)=}'
  77.     print(f'{type(A.f2)=}'
  78.  
  79.  
  80.     print(f'{A.g1=}'
  81.     print(f'{A.g2=}'
  82.  
  83.     print(f'{A().g1=}'
  84.     print(f'{A().g2=}'
  85.  
  86.     print(f'{type(A.g1)=}'
  87.     print(f'{type(A.g2)=}'
  88.  
  89. if __name__ == "__main__"
  90.  main() 

上面的類 StaticMethod 的作用相當于裝飾器 staticmethod,類ClassMethod 相當于裝飾器 classmethod。代碼的執行結果如下:

可以看出,StaticMethod 和 ClassMethod 的作用和標準庫的效果是一樣的,也可以看出 classmethod 和 staticmethod 的區別就在于 classmethod 帶有類的信息,可以調用類的構造函數,在編程中具有更好的擴展性。

最后的話

回答本文最初的問題,為什么 classmethod 更受標準庫的寵愛?是因為 classmethod 可以取代 staticmethod 的作用,而反過來卻不行。也就是說凡是使用 staticmethod 的地方,把 staticmethod 換成 classmethod,然后把函數增加第一個參數 cls,后面調用的代碼可以不變,反過來卻不行,也就是說 classmethod 的兼容性更好。

另一方面,classmethod 可以在內部再次調用類的構造函數,可以不修改現有實例生成新的實例,具有更強的靈活性和可擴展性,因此更受寵愛,當然這只是我的拙見,如果你有不同的想法,可以留言討論哈。

本文轉載自微信公眾號「Python七號」,可以通過以下二維碼關注。轉載本文請聯系Python七號公眾號。

 

責任編輯:武曉燕 來源: Python七號
相關推薦

2017-07-20 16:02:27

Python編程

2020-11-17 09:10:44

裝飾器

2015-07-31 16:29:15

DockerJavaLinux

2019-04-24 08:00:00

HTTPSHTTP前端

2018-06-21 08:50:53

2024-02-05 22:51:49

AGIRustPython

2015-01-06 09:37:58

2018-10-17 11:30:02

前后端代碼接口

2020-12-02 09:14:47

Apache批處理流式數據

2011-12-07 20:37:42

iOSAndroid谷歌

2023-01-10 15:00:44

2020-02-16 20:43:49

Python數據科學R

2019-02-24 22:05:12

JuliaPython語言

2018-10-07 05:08:11

2022-11-10 15:32:29

2021-01-13 10:51:08

PromissetTimeout(函數

2020-09-08 16:00:58

數據庫RedisMemcached

2019-11-29 09:29:12

互聯網SRE運維

2016-12-14 12:02:01

StormHadoop大數據

2017-02-14 14:20:02

StormHadoop
點贊
收藏

51CTO技術棧公眾號

日本少妇激情舌吻| 日本一本在线视频| 国产福利小视频在线观看| 久久一区中文字幕| 久久黄色av网站| 亚洲乱妇老熟女爽到高潮的片 | www.久久草.com| 夜夜精品浪潮av一区二区三区| 精品不卡在线| 亚洲专区第一页| 亚洲福利一区| 色噜噜久久综合伊人一本| 国产女人18毛片水真多18| 日本在线视频一区二区| 亚洲成人激情综合网| 日韩中文字幕av在线| 精品国产av一区二区| 久久久国产精品一区二区中文| 久久夜色精品国产欧美乱| 四季av综合网站| 日韩国产一二三区| 欧美日韩免费看| 色爽爽爽爽爽爽爽爽| 丝袜视频国产在线播放| 国产成人自拍网| 国产精品入口尤物| 日韩成人高清视频| 综合久久综合| 色综合伊人色综合网站| 深爱五月激情网| 91综合久久爱com| 欧美日韩在线观看一区二区| 欧美亚洲国产成人| 色屁屁www国产馆在线观看| 亚洲国产精品av| 久久久久资源| 婷婷视频在线观看| 成人午夜视频在线观看| 91中文字幕在线| 中文字幕在线播出| 三级欧美在线一区| 欧美怡春院一区二区三区| 久久综合综合久久| 综合久久一区| 操人视频在线观看欧美| 色www亚洲国产阿娇yao| 欧洲视频一区| 国产一区二区三区视频在线观看| yy1111111| 卡通动漫精品一区二区三区| 精品久久久久一区二区国产| 韩国三级hd中文字幕有哪些| 日韩不卡在线视频| 日韩欧美中文字幕制服| 中文字幕12页| 国产午夜精品一区在线观看| 制服丝袜日韩国产| 91蝌蚪视频在线| 国产精选久久| 日韩欧美视频在线| 一级网站在线观看| 日韩中文字幕无砖| 精品国产露脸精彩对白| 亚洲熟女一区二区| 神马日本精品| 亚洲欧美国产精品va在线观看| 91精品人妻一区二区三区蜜桃欧美| 国产精品主播在线观看| 日韩精品免费在线视频观看| a视频免费观看| 沈樵精品国产成av片| 亚洲欧美日韩视频一区| 貂蝉被到爽流白浆在线观看| 天天综合久久| 欧美高清激情视频| 国产污污视频在线观看| 久久资源在线| 成人有码在线视频| 亚洲第一大网站| 99热国产精品| 视频一区二区精品| 成人午夜在线影视| 亚洲国产你懂的| 亚洲中文字幕无码不卡电影| 懂色aⅴ精品一区二区三区| 6080日韩午夜伦伦午夜伦| 91精品人妻一区二区三区四区| 风间由美性色一区二区三区四区| 亚洲毛片在线观看| 99热6这里只有精品| 好看的亚洲午夜视频在线| 久久久久久久久久久国产| 狠狠人妻久久久久久| 精品制服美女丁香| 精品国产乱码久久久久久郑州公司| 蜜桃视频在线观看网站| 欧美国产乱子伦| 欧美交换配乱吟粗大25p| 久久影院午夜精品| 69堂国产成人免费视频| 人妻无码一区二区三区| 91精品国产视频| 青草青草久热精品视频在线网站| 中国女人一级一次看片| 成人综合激情网| 亚洲 国产 日韩 综合一区| 欧美高清另类hdvideosexjaⅴ| 欧美日韩免费观看中文| www.久久com| 精品免费视频| 97在线视频观看| 国产男女猛烈无遮挡| 久久精品亚洲国产奇米99| 天堂а√在线中文在线| 国产精品久久久久久久久免费高清 | 国产亚洲欧美一区| 国产在线免费视频| 麻豆成人综合网| 欧美精品123| 黑人玩欧美人三根一起进| 精品视频在线免费看| 亚洲国产精品成人综合久久久| 91精品国产自产在线观看永久∴| 国产成人亚洲综合91| 蜜桃视频久久一区免费观看入口| 国产精品成人免费在线| 黄色片久久久久| 久久夜色电影| 欧美激情免费观看| 精品国产乱码久久久久久蜜臀网站| 中文字幕av一区二区三区高| 麻豆av免费在线| 欧美变态挠脚心| 久久久久久久一| 精品黑人一区二区三区在线观看 | 亚洲国产精品久久久久秋霞蜜臀| 亚洲一级生活片| 麻豆精品在线看| 午夜午夜精品一区二区三区文| 亚洲黄色免费av| 亚洲精品久久7777777| 久久99久久久| 国产成人一区二区精品非洲| 久久av喷吹av高潮av| 久久亚洲精品人成综合网| 一区二区国产精品视频| 日韩成人一区二区三区| 成人午夜av在线| 欧美狂野激情性xxxx在线观| 亚洲**毛片| 欧美国产日韩一区二区| 午夜久久久久久久久久| 亚洲欧美另类小说| 免费成人黄色大片| 一区二区三区在线观看免费| 91欧美日韩一区| 黄色成人影院| 欧美成人综合网站| 九九视频免费在线观看| 懂色av一区二区三区蜜臀| 国产中文字幕乱人伦在线观看| 成人午夜网址| 欧美一级淫片播放口| 美丽的姑娘在线观看免费动漫| 色94色欧美sute亚洲线路一ni| 老头老太做爰xxx视频| 久久er99精品| 国产91沈先生在线播放| 国产精品zjzjzj在线观看| 97人人做人人爱| 成人三级黄色免费网站| 欧美日韩美女一区二区| 久久国产高清视频| 国产99久久久国产精品潘金网站| 97干在线视频| 精品产国自在拍| 91在线高清免费观看| 免费网站在线观看人| 日韩电影中文字幕一区| 中文字幕+乱码+中文| 综合久久综合久久| 国产精品扒开腿做爽爽爽a片唱戏| 亚洲在线一区| 亚洲一区二区三区午夜| 91久久精品无嫩草影院| 日本久久91av| а√天堂8资源在线官网| 亚洲第一区第二区| 欧美激情一区二区三区免费观看| 亚洲色图欧美偷拍| 国产一级二级在线观看| 美女在线视频一区| 给我免费播放片在线观看| 精品久久不卡| 国产精品swag| 九九九精品视频| 韩国日本不卡在线| 色哟哟免费在线观看| 精品粉嫩超白一线天av| 在线观看视频二区| 午夜精品久久久久久| 91ts人妖另类精品系列| 99久久er热在这里只有精品15| 中文字幕国产免费| 国产精品女主播一区二区三区| 一区二区在线观看网站| 亚洲警察之高压线| 96sao精品视频在线观看| 国产v综合v| 久久久久久欧美| 麻豆视频免费在线观看| 亚洲色图综合网| 你懂的网站在线| 欧美日产国产精品| 无码人妻精品一区二区三区9厂| 一区二区三区国产| 日韩一区二区在线看| 亚洲天堂黄色片| 国产日韩欧美不卡| 国产性生活毛片| 国产一区二区三区日韩| 四季av一区二区| 亚洲永久在线| 人妻夜夜添夜夜无码av | 亚洲视频在线观看视频| 刘玥91精选国产在线观看| 欧美久久久影院| 在线视频精品免费| 欧美日韩视频在线| 成人免费看片98| 亚洲欧美国产高清| 欧美性生交大片| 国产欧美中文在线| 免费看污片的网站| 91在线观看地址| 亚洲 欧美 日韩在线| 国产精品12区| 亚洲欧美日韩网站| 国产一区二区三区四区在线观看| 少妇网站在线观看| 日韩一区精品字幕| 男人的天堂日韩| 日韩精品乱码免费| 91淫黄看大片| 日本美女一区二区三区| 日韩精品一区中文字幕| 久久一区精品| 中文字幕有码av| 精品在线播放午夜| www.午夜av| 国产电影精品久久禁18| 香蕉视频xxxx| 成人一级视频在线观看| 国产伦精品一区二区免费| 99久久综合狠狠综合久久| 老熟妇精品一区二区三区| 久久综合久久综合亚洲| 青青草福利视频| 亚洲国产电影在线观看| 国产成人在线网址| 亚洲天堂网中文字| 国产av无码专区亚洲av毛网站| 亚洲六月丁香色婷婷综合久久 | 麻豆传媒免费在线观看| 在线精品亚洲| 国产精品果冻传媒潘| 6080亚洲理论片在线观看| 国产精品加勒比| 日韩欧美在线精品| 欧美日韩中文国产一区发布| 成人激情开心网| 男女啪啪的视频| 国产尤物精品| 国产91对白刺激露脸在线观看| 日韩激情视频网站| 91精品999| 成人久久18免费网站麻豆 | 国产精品午夜电影| 国产老头老太做爰视频| 亚洲丰满少妇videoshd| 中文字幕第四页| 欧美日韩精品是欧美日韩精品| 国产绿帽刺激高潮对白| 精品成人佐山爱一区二区| 黄色影院在线播放| 久久福利视频网| 国产网站在线| 国产日产欧美a一级在线| 一区二区在线免费播放| 欧美1o一11sex性hdhd| 欧美成人激情| 妞干网在线视频观看| 美腿丝袜一区二区三区| youjizz.com日本| 中文字幕乱码亚洲精品一区| 国产精彩视频在线观看| 在线观看亚洲一区| 亚洲精品人妻无码| 中文字幕欧美日韩| 91av久久| 91久久中文字幕| 欧美男gay| 免费看日本黄色| 日本亚洲免费观看| 色悠悠在线视频| 国产精品日日摸夜夜摸av| 日本一级黄色录像| 717成人午夜免费福利电影| 日韩av视屏| 久久99精品久久久久久琪琪| 成人看片在线观看| 成人在线视频网址| 97视频精品| 久久精品影视大全| 91亚洲资源网| 精品无码一区二区三区电影桃花| 欧美日韩激情一区二区三区| 欧洲一级在线观看| 欧美国产激情18| 国产亚洲精aa在线看| 天堂va久久久噜噜噜久久va| 国产日韩欧美高清免费| 涩视频在线观看| 亚洲色图欧美激情| 91精品中文字幕| 亚洲一区999| 中文字幕乱码中文乱码51精品 | 蜜桃tv一区二区三区| 成人免费在线网| 国产精品一区二区三区乱码| 久久精品色妇熟妇丰满人妻| 欧美性开放视频| 午夜视频在线免费播放| 久久综合久久综合久久| 成人免费观看cn| 成人免费毛片片v| 妺妺窝人体色www婷婷| 91精品一区二区三区在线观看| 成人福利在线| 国产精品青草久久久久福利99| 亚洲大片精品免费| 成人av一级片| 久久影音资源网| 天堂网中文字幕| 亚洲欧美成人网| 久久久人成影片一区二区三区在哪下载 | 欧美 国产 综合| a在线欧美一区| 日本熟伦人妇xxxx| 亚洲精品成人久久| 麻豆mv在线观看| 麻豆精品视频| 三级在线观看一区二区| 国产成人一区二区在线观看| 在线观看国产一区二区| 高清在线观看av| 国产一区香蕉久久| 欧美二区视频| 久久久午夜精品福利内容| 岛国av一区二区三区| 深夜福利在线看| 国产精品久久久久av免费| 日韩在线不卡| 天天爽夜夜爽视频| 亚洲午夜羞羞片| 日韩av资源站| 国产免费一区二区三区在线能观看| 欧美高清视频在线观看mv| 男女污污视频网站| 亚洲一卡二卡三卡四卡| 天堂成人在线| 国产精品欧美久久久| 伊人久久大香线| 欲求不满的岳中文字幕| 色哟哟亚洲精品| 永久av在线| 国产精品v欧美精品∨日韩| 国产日韩欧美三区| 欧美另类z0zx974| 日韩一级视频免费观看在线| h片在线观看视频免费| 久久综合久久久| 九九久久精品视频| 日产电影一区二区三区| 亚洲视频在线免费观看| 91精品麻豆| www.99热这里只有精品| 国产色一区二区| 午夜精品一二三区| 国产成人精品网站| 欧美一区二区三区另类 | 亚洲欧洲av在线| 日本人妻丰满熟妇久久久久久| 国产精品国产自产拍高清av水多| 一区二区三区网站| 波多野在线播放| 精品国产伦一区二区三区观看方式| 亚洲综合在线电影| 996这里只有精品| 国产精品三级av在线播放|