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 修飾的方法稱為:靜態(tài)方法,和普通的函數(shù)沒(méi)有什么區(qū)別
下面將聊聊實(shí)際項(xiàng)目中幾種應(yīng)用場(chǎng)景
1、要調(diào)用一個(gè)靜態(tài)方法,一般使用形式是:「 類名.方法名() 」
class Web(object):
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
pass
if __name__ == '__main__':
# 直接使用類名+方法名調(diào)用
Web.foo_staticmethod()
當(dāng)然,也可以實(shí)例化一個(gè)類對(duì)象,通過(guò)這個(gè)對(duì)象去調(diào)用靜態(tài)方法,但是不建議使用這種方式
# 實(shí)例化一個(gè)對(duì)象
instance = Web()
# 使用實(shí)例對(duì)象去調(diào)用靜態(tài)方法(不建議)
instance.foo_staticmethod()
2、針對(duì)類中定義的靜態(tài)變量,可以使用「 類名.變量名 」 的形式去訪問(wèn)
class Web(object):
# 靜態(tài)變量(類變量)
name = "Python_Web"
@staticmethod
def foo_staticmethod():
"""靜態(tài)方法"""
# 引用靜態(tài)變量
print(Web.name)
3、靜態(tài)方法內(nèi)部使用其他靜態(tài)方法、類方法,同樣是使用「 類名.方法名() 」去調(diào)用
class Web(object):
# 靜態(tài)變量(類變量)
name = "Python_Web"
# 類方法
@classmethod
def foo_classmethod_other(cls):
print('類方法被調(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)用類方法
print(Web.foo_classmethod_other())
4、靜態(tài)方法內(nèi)部調(diào)用普通方法,訪問(wèn)實(shí)例屬性
普通方法和實(shí)例屬性都必須通過(guò)實(shí)例對(duì)象去引用,不能直接使用類名去訪問(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、子類的使用
在子類中調(diào)用父類定義好的靜態(tài)方法,只需要將類名替換為子類名稱即可
class Web(object):
@staticmethod
def foo_staticmethod(arg1, arg2):
pass
class Django(Web):
"""子類"""
pass
if __name__ == '__main__':
# 1、使用類名(父類)去調(diào)用靜態(tài)方法
Web.foo_staticmethod("Hello", ",AirPython")
# 2、使用類名(子類)去調(diào)用靜態(tài)方法
Django.foo_staticmethod("Hello", ",AirPython")
3.@classmethod
裝飾器 @classmethod 修飾的方法稱為:類方法,在使用的時(shí)候,會(huì)將類本身作為第一個(gè)參數(shù) cls 傳遞給類方法
# 類方法,第一個(gè)參數(shù)為cls,代表類本身
@classmethod
def foo_classmethod(cls):
pass
其中,cls 代表外層類本身,可以實(shí)例化,也可以直接調(diào)用靜態(tài)方法、類方法、靜態(tài)變量
下面逐一進(jìn)行說(shuō)明
1、要調(diào)用一個(gè)類方法,一般使用形式是:「 類名.方法名() 」
class Web(object):
# 類方法,第一個(gè)參數(shù)為cls,代表類本身
@classmethod
def foo_classmethod(cls):
pass
if __name__ == '__main__':
# 使用類名去調(diào)用類方法
Web.foo_classmethod()
和靜態(tài)方法類似,也可以實(shí)例化一個(gè)類對(duì)象,通過(guò)這個(gè)對(duì)象去調(diào)用靜態(tài)方法,但是不建議使用這種方式
2、調(diào)用靜態(tài)變量
靜態(tài)方法內(nèi)部引用靜態(tài)變量有兩種方式,分別是:
- 「 類名.變量名 」
- 「 cls.變量名 」
注意:由于 cls 代表就是外層類本身,所以這兩種方式等效
class Web(object):
# 靜態(tài)變量(類變量)
name = "Python_Web"
# 類方法,第一個(gè)參數(shù)為cls,代表類本身
@classmethod
def foo_classmethod(cls):
# 調(diào)用靜態(tài)變量方式一
print(cls.name)
# 調(diào)用靜態(tài)變量方式二
print(Web.name)
3、類方法內(nèi)部調(diào)用其他類方法、靜態(tài)方法
在一個(gè)類方法內(nèi)部,可以使用「 類名.類方法名() 」、「 類名.靜態(tài)方法名() 」的形式去調(diào)用方法
class Web(object):
# 靜態(tài)方法
@staticmethod
def foo_staticmethod():
print('靜態(tài)方法被調(diào)用!')
# 其他類方法
@classmethod
def foo_classmethod_other(cls):
print('另外一個(gè)類方法被調(diào)用!')
# 類方法,第一個(gè)參數(shù)為cls,代表類本身
@classmethod
def foo_classmethod(cls):
# 調(diào)用其他類方法
cls.foo_classmethod_other()
# 調(diào)用靜態(tài)方法
cls.foo_staticmethod()
if __name__ == '__main__':
Web.foo_classmethod()
4、類方法內(nèi)部調(diào)用普通方法,訪問(wèn)實(shí)例屬性
需要通過(guò) cls 變量實(shí)例化一個(gè)類對(duì)象,然后通過(guò)這個(gè)對(duì)象去調(diào)用普通方法和實(shí)例屬性
class Web(object):
def __init__(self):
self.desc = "實(shí)例屬性,不共享"
def norm_method(self):
"""普通方法"""
print('普通方法被調(diào)用!')
# 類方法,第一個(gè)參數(shù)為cls,代表類本身
@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、子類的使用
在子類中調(diào)用父類定義好的類方法,只需要將類名替換為子類名稱即可,代碼和靜態(tài)方法類似
4.區(qū)別
下面總結(jié)一下普通方法、靜態(tài)方法、類方法的區(qū)別
- 普通方法:第一個(gè)參數(shù) self 代表實(shí)例對(duì)象本身,可以使用 self 直接引用定義的實(shí)例屬性和普通方法;如果需要調(diào)用靜態(tài)方法和類方法,通過(guò)「 類名.方法名() 」調(diào)用即可
- 靜態(tài)方法:使用「 類名.靜態(tài)變量 」引用靜態(tài)變量,利用「 類名.方法名() 」調(diào)用其他靜態(tài)方法和類方法;如果需要調(diào)用普通方法,需要先實(shí)例化一個(gè)對(duì)象,然后利用對(duì)象去調(diào)用普通方法
- 類方法:第一個(gè)參數(shù) cls 代表類本身(等價(jià)),通過(guò)「 cls.靜態(tài)變量 」或「 類名.靜態(tài)變量 」引用靜態(tài)變量,利用「 cls.方法名() 」或「 類名.方法名() 」去調(diào)用靜態(tài)方法和類方法;如果需要調(diào)用普通方法,需要先實(shí)例化一個(gè)對(duì)象,然后利用對(duì)象去調(diào)用普通方法
- 靜態(tài)方法和類方法是針對(duì)類定義的,除了可以使用類名去調(diào)用,也可以使用實(shí)例對(duì)象去調(diào)用,但是不建議
5.最后
一般來(lái)說(shuō),如果方法內(nèi)部涉及到實(shí)例對(duì)象屬性的操作,建議用普通方法;如果方法內(nèi)部沒(méi)有操作實(shí)例屬性的操作,僅僅包含一些工具性的操作,建議使用靜態(tài)方法;而如果需要對(duì)類屬性,即靜態(tài)變量進(jìn)行限制性操作,則建議使用類方法
-
編碼
+關(guān)注
關(guān)注
6文章
935瀏覽量
54771 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4308瀏覽量
62444 -
靜態(tài)
+關(guān)注
關(guān)注
1文章
29瀏覽量
14532 -
python
+關(guān)注
關(guān)注
56文章
4783瀏覽量
84473
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論