Python的靜態方法和類成員方法
Python的靜態方法和類成員方法都可以被類或例項訪問,兩者概念不容易理清,但還是有區別的:
- 靜態方法無需傳入self引數,類成員方法需傳入代表本類的cls引數;
- 從第1條,靜態方法是無法訪問例項變數的,而類成員方法也同樣無法訪問例項變數,但可以訪問類變數;
- 靜態方法有點像函式工具庫的作用,而類成員方法則更接近類似Java物件導向概念中的靜態方法。
實現靜態方法和類方法的兩種方式
一、在Python 2.3及之前,用staticmethod和classmethod型別物件包裝實現
例子如下(注意print裡的說明):
class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2'
def staticmd():
print '靜態方法,無法訪問val1和val2'
smd = staticmethod(staticmd)
def classmd(cls):
print '類方法,類:' + str(cls) + ',val1:' + cls.val1 + ',無法訪問val2的值'
cmd = classmethod(classmd)
執行:
>>> mc = MyClass()
>>> mc.smd()
>>> mc.cmd()
>>> MyClass.smd()
>>> MyClass.cmd()
二、在Python 2.4及之後,用裝飾器(decorators)實現
裝飾器使用@操作符,例子如下:
class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2'
@staticmethod
def staticmd():
print '靜態方法,無法訪問val1和val2'
@classmethod
def classmd(cls):
print '類方法,類:' + str(cls) + ',val1:' + cls.val1 + ',無法訪問val2的值'
不管是以上兩種方式中的哪一種,執行情況都是一樣的,以方式二執行結果為例分析如下:
執行:
>>> mc = MyClass() # 例項化
>>> mc.staticmd() # 例項呼叫靜態方法,無法訪問例項變數val1和val2
>>>
靜態方法,無法訪問val1和val2
>>> mc.classmd() # 例項呼叫類方法,注意,這裡訪問的是類MyClass的變數val1的值,不是例項化後mc的例項變數val1,這裡容易混淆,往下看就會明白。val2一直是例項變數,所以無法訪問
>>>
類方法,類:__main__.MyClass,val1:Value 1,無法訪問val2的值
>>> MyClass.staticmd() # 類直接呼叫靜態方法,結果同上面的例項呼叫,無論是類變數還是例項變數都無法訪問
>>>
靜態方法,無法訪問val1和val2
>>> MyClass.classmd() # 類直接呼叫類方法,結果同上面的例項呼叫
>>>
類方法,類:__main__.MyClass,val1:Value 1,無法訪問val2的值
>>> mc.val1 = 'Value changed' # 改變例項變數val1的值
>>> mc.classmd() # 例項呼叫類方法,注意到cls.val1的值沒變,所以,這時的cls.val1是類變數val1,而非例項變數val1
>>>
類方法,類:__main__.MyClass,val1:Value 1,無法訪問val2的值
>>> MyClass.classmd() # 類直接呼叫類方法,結果同上面的例項呼叫
>>>
類方法,類:__main__.MyClass,val1:Value 1,無法訪問val2的值
>>> MyClass.val1 = 'Class Value changed' # 改變類變數val1的值
>>> mc.classmd() # 例項呼叫類方法,注意到cls.val1的值變了,所以,進一步證明了這時的cls.val1是類變數val1,而非例項變數val1
>>>
類方法,類:__main__.MyClass,val1:Class Value changed,無法訪問val2的值
>>> MyClass.classmd() # 類直接呼叫類方法,結果同上面的例項呼叫
>>>
類方法,類:__main__.MyClass,val1:Class Value changed,無法訪問val2的值
結論
如果上述執行過程太複雜,記住以下兩點就好了:
靜態方法:無法訪問類屬性、例項屬性,相當於一個相對獨立的方法,跟類其實沒什麼關係,換個角度來講,其實就是放在一個類的作用域裡的函式而已。
類成員方法:可以訪問類屬性,無法訪問例項屬性。上述的變數val1,在類裡是類變數,在例項中又是例項變數,所以容易混淆。
相關文章
- 微課|中學生可以這樣學Python(7.3.3節):成員方法、類方法、靜態方法Python
- C++類中的常成員和靜態成員C++
- python入門基礎(14)--類的屬性、成員方法、靜態方法以及繼承、過載Python繼承
- 類的靜態屬性和方法
- 靜態方法和普通的成員方法||分配記憶體空間的區別記憶體
- c++類的靜態成員C++
- C++:類的靜態成員C++
- [Python 基礎] Python 例項方法、靜態方法和類方法詳解 (包含區別和用法)Python
- 類內的靜態成員函式函式
- 『無為則無心』Python物件導向 — 58、類方法和靜態方法Python物件
- c#物件導向- 靜態成員和非靜態成員的區別C#物件
- C#快速入門教程(3)——類的靜態成員和例項成員C#
- Python - 物件導向程式設計 - 例項方法、靜態方法、類方法Python物件程式設計
- oop類的繼承與類靜態成員學習OOP繼承
- Python常見面試題006 類方法、類例項方法、靜態方法有何區別?Python面試題
- MFC之動態呼叫自己寫的類庫中的類的成員方法
- Java的方法靜態方法Java
- net 靜態方法與非靜態方法
- javaSE-day04--ArrayList基本用方法、類內定義方法和方法過載、靜態方法static(類的方法)、工具方法(static)的定義和使用Java
- 類的靜態成員變數和普通成員變數該怎樣去區別定義變數
- C++類的靜態成員變數初始化C++變數
- Java類、物件以及(靜態)方法的探討Java物件
- 14 #### 方法分類與使用場景(繫結、靜態、類方法)
- 靜態方法
- c++中的靜態成員C++
- Python中動態類和動態方法的建立與呼叫Python
- 靜態域與靜態方法
- TypeScript 中 class 的例項成員與靜態成員TypeScript
- Java 通過反射獲取類的資訊(成員變數,成員方法,構造方法)Java反射變數構造方法
- ES6中類的靜態方法=> static 的使用
- python建立類和類方法Python
- 靜態工廠方法和例項工廠方法
- 【python】類的特殊成員Python
- Python靜態方法,其實暗藏玄機Python
- Object上的靜態方法Object
- static靜態方法的使用
- 對於靜態成員來說是類的建構函式,對於例項成員是類的原型物件。函式原型物件
- 全網最適合入門的物件導向程式設計教程:14 類和物件的 Python 實現-類的靜態方法和類方法,你分得清嗎?物件程式設計Python
- 關於如何在Python中使用靜態、類或抽象方法的權威指南Python抽象