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 靜態方法和類方法的區別Python
- 微課|中學生可以這樣學Python(7.3.3節):成員方法、類方法、靜態方法Python
- C++類中的常成員和靜態成員C++
- Java的靜態成員類Java
- Python例項方法、類方法、靜態方法Python
- Python Class 的例項方法/類方法/靜態方法Python
- python入門基礎(14)--類的屬性、成員方法、靜態方法以及繼承、過載Python繼承
- c++類的靜態成員C++
- C++:類的靜態成員C++
- C++ 類的靜態成員C++
- 靜態資料成員和靜態成員函式函式
- 類的靜態屬性和方法
- 靜態方法和普通的成員方法||分配記憶體空間的區別記憶體
- C++類靜態成員C++
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- 類內的靜態成員函式函式
- c#物件導向- 靜態成員和非靜態成員的區別C#物件
- C#快速入門教程(3)——類的靜態成員和例項成員C#
- [Python 基礎] Python 例項方法、靜態方法和類方法詳解 (包含區別和用法)Python
- Python關於反射和類的特殊成員方法詳解Python反射
- Python的靜態方法和類成員方法都可以被類或例項訪問,兩者概念不容易理清,但還是有區別的Python
- 『無為則無心』Python物件導向 — 58、類方法和靜態方法Python物件
- 注意!非靜態內部類和非靜態方法的匿名類的this$0屬性
- oop類的繼承與類靜態成員學習OOP繼承
- Python - 物件導向程式設計 - 例項方法、靜態方法、類方法Python物件程式設計
- 靜態方法查詢類名
- MFC之動態呼叫自己寫的類庫中的類的成員方法
- c# 用反射獲得靜態類成員C#反射
- 類的靜態成員變數和普通成員變數該怎樣去區別定義變數
- Java的方法靜態方法Java
- Python常見面試題006 類方法、類例項方法、靜態方法有何區別?Python面試題
- net 靜態方法與非靜態方法
- C++類的靜態成員變數初始化C++變數
- 物件導向2--靜態方法、類方法、屬性方法物件
- javaSE-day04--ArrayList基本用方法、類內定義方法和方法過載、靜態方法static(類的方法)、工具方法(static)的定義和使用Java
- Java 通過反射獲取類的資訊(成員變數,成員方法,構造方法)Java反射變數構造方法
- c++中的靜態成員C++
- js--Object的靜態方法和例項方法JSObject