1. 場(chǎng)景
前幾天,有一個(gè)小伙伴過(guò)來(lái)問(wèn)我,Python 中的 @staticmethod、@classmethod、self、cls 分別代表什么意思,自己平時(shí)光顧著用,不知道具體的含義?
事實(shí)上,由于 Python 語(yǔ)言的靈活性,這部分內(nèi)容在日常編碼過(guò)程中,很容易被忽略掉
本篇文章將和大家一起聊聊這幾個(gè)小知識(shí)點(diǎn)
2.@staticmethod
裝飾器 @staticmethod 修飾的方法稱(chēng)為:靜態(tài)方法,和普通的函數(shù)沒(méi)有什么區(qū)別
下面將聊聊實(shí)際項(xiàng)目中幾種應(yīng)用場(chǎng)景
1、要調(diào)用一個(gè)靜態(tài)方法,一般使用形式是:「 類(lèi)名.方法名() 」
class Web(object):
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
pass
if __name__ == '__main__':
# 直接使用類(lèi)名+方法名調(diào)用
Web.foo_staticmethod()
當(dāng)然,也可以實(shí)例化一個(gè)類(lèi)對(duì)象,通過(guò)這個(gè)對(duì)象去調(diào)用靜態(tài)方法,但是不建議使用這種方式
# 實(shí)例化一個(gè)對(duì)象
instance = Web()
# 使用實(shí)例對(duì)象去調(diào)用靜態(tài)方法(不建議)
instance.foo_staticmethod()
2、針對(duì)類(lèi)中定義的靜態(tài)變量,可以使用「 類(lèi)名.變量名 」 的形式去訪問(wèn)
class Web(object):
# 靜態(tài)變量(類(lèi)變量)
name = "Python_Web"
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
# 引用靜態(tài)變量
print(Web.name)
3、靜態(tài)方法內(nèi)部使用其他靜態(tài)方法、類(lèi)方法,同樣是使用「 類(lèi)名.方法名() 」去調(diào)用
class Web(object):
# 靜態(tài)變量(類(lèi)變量)
name = "Python_Web"
# 類(lèi)方法
@classmethod
def foo_classmethod_other(cls):
print('類(lèi)方法被調(diào)用!')
# 另外一個(gè)靜態(tài)方法
@staticmethod
def foo_staticmethod_other():
print('另外一個(gè)靜態(tài)方法被調(diào)用!')
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
# 調(diào)用其他靜態(tài)方法
print(Web.foo_staticmethod_other())
# 調(diào)用類(lèi)方法
print(Web.foo_classmethod_other())
4、靜態(tài)方法內(nèi)部調(diào)用普通方法,訪問(wèn)實(shí)例屬性
普通方法和實(shí)例屬性都必須通過(guò)實(shí)例對(duì)象去引用,不能直接使用類(lèi)名去訪問(wèn)
class Web(object):
def __init__(self):
self.desc = "實(shí)例屬性,不共享"
def norm_method(self):
"""普通方法"""
print('普通方法被調(diào)用!')
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
instance = Web()
# 獲取實(shí)例屬性
print(instance.desc)
# 調(diào)用普通方法
instance.norm_method()
5、子類(lèi)的使用
在子類(lèi)中調(diào)用父類(lèi)定義好的靜態(tài)方法,只需要將類(lèi)名替換為子類(lèi)名稱(chēng)即可
class Web(object):
@staticmethod
def foo_staticmethod(arg1, arg2):
pass
class Django(Web):
"""子類(lèi)"""
pass
if __name__ == '__main__':
# 1、使用類(lèi)名(父類(lèi))去調(diào)用靜態(tài)方法
Web.foo_staticmethod("Hello", ",AirPython")
# 2、使用類(lèi)名(子類(lèi))去調(diào)用靜態(tài)方法
Django.foo_staticmethod("Hello", ",AirPython")
3.@classmethod
裝飾器 @classmethod 修飾的方法稱(chēng)為:類(lèi)方法,在使用的時(shí)候,會(huì)將類(lèi)本身作為第一個(gè)參數(shù) cls 傳遞給類(lèi)方法
# 類(lèi)方法,第一個(gè)參數(shù)為cls,代表類(lèi)本身
@classmethod
def foo_classmethod(cls):
pass
其中,cls 代表外層類(lèi)本身,可以實(shí)例化,也可以直接調(diào)用靜態(tài)方法、類(lèi)方法、靜態(tài)變量
下面逐一進(jìn)行說(shuō)明
1、要調(diào)用一個(gè)類(lèi)方法,一般使用形式是:「 類(lèi)名.方法名() 」
class Web(object):
# 類(lèi)方法,第一個(gè)參數(shù)為cls,代表類(lèi)本身
@classmethod
def foo_classmethod(cls):
pass
if __name__ == '__main__':
# 使用類(lèi)名去調(diào)用類(lèi)方法
Web.foo_classmethod()
和靜態(tài)方法類(lèi)似,也可以實(shí)例化一個(gè)類(lèi)對(duì)象,通過(guò)這個(gè)對(duì)象去調(diào)用靜態(tài)方法,但是不建議使用這種方式
2、調(diào)用靜態(tài)變量
靜態(tài)方法內(nèi)部引用靜態(tài)變量有兩種方式,分別是:
- 「 類(lèi)名.變量名 」
- 「 cls.變量名 」
注意:由于 cls 代表就是外層類(lèi)本身,所以這兩種方式等效
class Web(object):
# 靜態(tài)變量(類(lèi)變量)
name = "Python_Web"
# 類(lèi)方法,第一個(gè)參數(shù)為cls,代表類(lèi)本身
@classmethod
def foo_classmethod(cls):
# 調(diào)用靜態(tài)變量方式一
print(cls.name)
# 調(diào)用靜態(tài)變量方式二
print(Web.name)
3、類(lèi)方法內(nèi)部調(diào)用其他類(lèi)方法、靜態(tài)方法
在一個(gè)類(lèi)方法內(nèi)部,可以使用「 類(lèi)名.類(lèi)方法名() 」、「 類(lèi)名.靜態(tài)方法名() 」的形式去調(diào)用方法
class Web(object):
# 靜態(tài)方法
@staticmethod
def foo_staticmethod():
print('靜態(tài)方法被調(diào)用!')
# 其他類(lèi)方法
@classmethod
def foo_classmethod_other(cls):
print('另外一個(gè)類(lèi)方法被調(diào)用!')
# 類(lèi)方法,第一個(gè)參數(shù)為cls,代表類(lèi)本身
@classmethod
def foo_classmethod(cls):
# 調(diào)用其他類(lèi)方法
cls.foo_classmethod_other()
# 調(diào)用靜態(tài)方法
cls.foo_staticmethod()
if __name__ == '__main__':
Web.foo_classmethod()
4、類(lèi)方法內(nèi)部調(diào)用普通方法,訪問(wèn)實(shí)例屬性
需要通過(guò) cls 變量實(shí)例化一個(gè)類(lèi)對(duì)象,然后通過(guò)這個(gè)對(duì)象去調(diào)用普通方法和實(shí)例屬性
class Web(object):
def __init__(self):
self.desc = "實(shí)例屬性,不共享"
def norm_method(self):
"""普通方法"""
print('普通方法被調(diào)用!')
# 類(lèi)方法,第一個(gè)參數(shù)為cls,代表類(lèi)本身
@classmethod
def foo_classmethod(cls):
# 如果要調(diào)用實(shí)例屬性,必須使用cls實(shí)例化一個(gè)對(duì)象,然后再去引用
print(cls().desc)
# 如果要調(diào)用普通方法,必須使用cls實(shí)例化一個(gè)對(duì)象,然后再去引用
cls().norm_method()
5、子類(lèi)的使用
在子類(lèi)中調(diào)用父類(lèi)定義好的類(lèi)方法,只需要將類(lèi)名替換為子類(lèi)名稱(chēng)即可,代碼和靜態(tài)方法類(lèi)似
4.區(qū)別
下面總結(jié)一下普通方法、靜態(tài)方法、類(lèi)方法的區(qū)別
- 普通方法:第一個(gè)參數(shù) self 代表實(shí)例對(duì)象本身,可以使用 self 直接引用定義的實(shí)例屬性和普通方法;如果需要調(diào)用靜態(tài)方法和類(lèi)方法,通過(guò)「 類(lèi)名.方法名() 」調(diào)用即可
- 靜態(tài)方法:使用「 類(lèi)名.靜態(tài)變量 」引用靜態(tài)變量,利用「 類(lèi)名.方法名() 」調(diào)用其他靜態(tài)方法和類(lèi)方法;如果需要調(diào)用普通方法,需要先實(shí)例化一個(gè)對(duì)象,然后利用對(duì)象去調(diào)用普通方法
- 類(lèi)方法:第一個(gè)參數(shù) cls 代表類(lèi)本身(等價(jià)),通過(guò)「 cls.靜態(tài)變量 」或「 類(lèi)名.靜態(tài)變量 」引用靜態(tài)變量,利用「 cls.方法名() 」或「 類(lèi)名.方法名() 」去調(diào)用靜態(tài)方法和類(lèi)方法;如果需要調(diào)用普通方法,需要先實(shí)例化一個(gè)對(duì)象,然后利用對(duì)象去調(diào)用普通方法
- 靜態(tài)方法和類(lèi)方法是針對(duì)類(lèi)定義的,除了可以使用類(lèi)名去調(diào)用,也可以使用實(shí)例對(duì)象去調(diào)用,但是不建議
5.最后
一般來(lái)說(shuō),如果方法內(nèi)部涉及到實(shí)例對(duì)象屬性的操作,建議用普通方法;如果方法內(nèi)部沒(méi)有操作實(shí)例屬性的操作,僅僅包含一些工具性的操作,建議使用靜態(tài)方法;而如果需要對(duì)類(lèi)屬性,即靜態(tài)變量進(jìn)行限制性操作,則建議使用類(lèi)方法
-
編碼
+關(guān)注
關(guān)注
6文章
1039瀏覽量
56964 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4417瀏覽量
67499 -
靜態(tài)
+關(guān)注
關(guān)注
1文章
30瀏覽量
14840 -
python
+關(guān)注
關(guān)注
57文章
4876瀏覽量
90022
發(fā)布評(píng)論請(qǐng)先 登錄
動(dòng)態(tài)庫(kù)封裝成python模塊的方法
Python多重繼承使用方法
如何使用Python的類(lèi)? 優(yōu)勢(shì)有哪些?
Python中的類(lèi)方法、實(shí)例方法和靜態(tài)方法?
請(qǐng)問(wèn)Python中的類(lèi)方法、實(shí)例方法和靜態(tài)方法是什么?
傳統(tǒng)靜態(tài)配置方法與動(dòng)態(tài)配置方法的區(qū)別在哪?
python靜態(tài)方法與類(lèi)方法
python執(zhí)行函數(shù)的九種方法
ASIC靜態(tài)驗(yàn)證方法
python基礎(chǔ)教程之如何進(jìn)行靜態(tài)方法和類(lèi)方法詳細(xì)筆記說(shuō)明
Python中普通方法、靜態(tài)方法、類(lèi)方法的區(qū)別
評(píng)論