1. 場景
前幾天,有一個小伙伴過來問我,Python 中的 @staticmethod、@classmethod、self、cls 分別代表什么意思,自己平時光顧著用,不知道具體的含義?
事實上,由于 Python 語言的靈活性,這部分內容在日常編碼過程中,很容易被忽略掉
本篇文章將和大家一起聊聊這幾個小知識點
2.@staticmethod
裝飾器 @staticmethod 修飾的方法稱為:靜態方法,和普通的函數沒有什么區別
下面將聊聊實際項目中幾種應用場景
1、要調用一個靜態方法,一般使用形式是:「 類名.方法名() 」
class Web(object):
@staticmethod
def foo_staticmethod():
"""靜態方法"""
pass
if __name__ == '__main__':
# 直接使用類名+方法名調用
Web.foo_staticmethod()
當然,也可以實例化一個類對象,通過這個對象去調用靜態方法,但是不建議使用這種方式
# 實例化一個對象
instance = Web()
# 使用實例對象去調用靜態方法(不建議)
instance.foo_staticmethod()
2、針對類中定義的靜態變量,可以使用「 類名.變量名 」 的形式去訪問
class Web(object):
# 靜態變量(類變量)
name = "Python_Web"
@staticmethod
def foo_staticmethod():
"""靜態方法"""
# 引用靜態變量
print(Web.name)
3、靜態方法內部使用其他靜態方法、類方法,同樣是使用「 類名.方法名() 」去調用
class Web(object):
# 靜態變量(類變量)
name = "Python_Web"
# 類方法
@classmethod
def foo_classmethod_other(cls):
print('類方法被調用!')
# 另外一個靜態方法
@staticmethod
def foo_staticmethod_other():
print('另外一個靜態方法被調用!')
@staticmethod
def foo_staticmethod():
"""靜態方法"""
# 調用其他靜態方法
print(Web.foo_staticmethod_other())
# 調用類方法
print(Web.foo_classmethod_other())
4、靜態方法內部調用普通方法,訪問實例屬性
普通方法和實例屬性都必須通過實例對象去引用,不能直接使用類名去訪問
class Web(object):
def __init__(self):
self.desc = "實例屬性,不共享"
def norm_method(self):
"""普通方法"""
print('普通方法被調用!')
@staticmethod
def foo_staticmethod():
"""靜態方法"""
instance = Web()
# 獲取實例屬性
print(instance.desc)
# 調用普通方法
instance.norm_method()
5、子類的使用
在子類中調用父類定義好的靜態方法,只需要將類名替換為子類名稱即可
class Web(object):
@staticmethod
def foo_staticmethod(arg1, arg2):
pass
class Django(Web):
"""子類"""
pass
if __name__ == '__main__':
# 1、使用類名(父類)去調用靜態方法
Web.foo_staticmethod("Hello", ",AirPython")
# 2、使用類名(子類)去調用靜態方法
Django.foo_staticmethod("Hello", ",AirPython")
3.@classmethod
裝飾器 @classmethod 修飾的方法稱為:類方法,在使用的時候,會將類本身作為第一個參數 cls 傳遞給類方法
# 類方法,第一個參數為cls,代表類本身
@classmethod
def foo_classmethod(cls):
pass
其中,cls 代表外層類本身,可以實例化,也可以直接調用靜態方法、類方法、靜態變量
下面逐一進行說明
1、要調用一個類方法,一般使用形式是:「 類名.方法名() 」
class Web(object):
# 類方法,第一個參數為cls,代表類本身
@classmethod
def foo_classmethod(cls):
pass
if __name__ == '__main__':
# 使用類名去調用類方法
Web.foo_classmethod()
和靜態方法類似,也可以實例化一個類對象,通過這個對象去調用靜態方法,但是不建議使用這種方式
2、調用靜態變量
靜態方法內部引用靜態變量有兩種方式,分別是:
- 「 類名.變量名 」
- 「 cls.變量名 」
注意:由于 cls 代表就是外層類本身,所以這兩種方式等效
class Web(object):
# 靜態變量(類變量)
name = "Python_Web"
# 類方法,第一個參數為cls,代表類本身
@classmethod
def foo_classmethod(cls):
# 調用靜態變量方式一
print(cls.name)
# 調用靜態變量方式二
print(Web.name)
3、類方法內部調用其他類方法、靜態方法
在一個類方法內部,可以使用「 類名.類方法名() 」、「 類名.靜態方法名() 」的形式去調用方法
class Web(object):
# 靜態方法
@staticmethod
def foo_staticmethod():
print('靜態方法被調用!')
# 其他類方法
@classmethod
def foo_classmethod_other(cls):
print('另外一個類方法被調用!')
# 類方法,第一個參數為cls,代表類本身
@classmethod
def foo_classmethod(cls):
# 調用其他類方法
cls.foo_classmethod_other()
# 調用靜態方法
cls.foo_staticmethod()
if __name__ == '__main__':
Web.foo_classmethod()
4、類方法內部調用普通方法,訪問實例屬性
需要通過 cls 變量實例化一個類對象,然后通過這個對象去調用普通方法和實例屬性
class Web(object):
def __init__(self):
self.desc = "實例屬性,不共享"
def norm_method(self):
"""普通方法"""
print('普通方法被調用!')
# 類方法,第一個參數為cls,代表類本身
@classmethod
def foo_classmethod(cls):
# 如果要調用實例屬性,必須使用cls實例化一個對象,然后再去引用
print(cls().desc)
# 如果要調用普通方法,必須使用cls實例化一個對象,然后再去引用
cls().norm_method()
5、子類的使用
在子類中調用父類定義好的類方法,只需要將類名替換為子類名稱即可,代碼和靜態方法類似
4.區別
下面總結一下普通方法、靜態方法、類方法的區別
- 普通方法:第一個參數 self 代表實例對象本身,可以使用 self 直接引用定義的實例屬性和普通方法;如果需要調用靜態方法和類方法,通過「 類名.方法名() 」調用即可
- 靜態方法:使用「 類名.靜態變量 」引用靜態變量,利用「 類名.方法名() 」調用其他靜態方法和類方法;如果需要調用普通方法,需要先實例化一個對象,然后利用對象去調用普通方法
- 類方法:第一個參數 cls 代表類本身(等價),通過「 cls.靜態變量 」或「 類名.靜態變量 」引用靜態變量,利用「 cls.方法名() 」或「 類名.方法名() 」去調用靜態方法和類方法;如果需要調用普通方法,需要先實例化一個對象,然后利用對象去調用普通方法
- 靜態方法和類方法是針對類定義的,除了可以使用類名去調用,也可以使用實例對象去調用,但是不建議
5.最后
一般來說,如果方法內部涉及到實例對象屬性的操作,建議用普通方法;如果方法內部沒有操作實例屬性的操作,僅僅包含一些工具性的操作,建議使用靜態方法;而如果需要對類屬性,即靜態變量進行限制性操作,則建議使用類方法
-
編碼
+關注
關注
6文章
940瀏覽量
54814 -
函數
+關注
關注
3文章
4327瀏覽量
62573 -
靜態
+關注
關注
1文章
29瀏覽量
14542 -
python
+關注
關注
56文章
4792瀏覽量
84628
發布評論請先 登錄
相關推薦
評論