標籤:區別 混淆 利用 org and 改變 邏輯 c++ ima
http://blog.csdn.net/pipisorry/article/details/49516185
面相對象程式設計中,類方法和靜態方法是經常用到的兩個術語。
邏輯上講:類方法是只能由類名調用;靜態方法可以由類名或對象名進行調用。
在C++中,靜態方法與類方法邏輯上是等價的,只有一個概念,不會混淆。
在python中,方法分為三類執行個體方法、類方法、靜態方法。
@classmethod和@staticmethod
他們的使用情境並不一樣。在python中,兩種方法的主要區別在於參數
- 類內部普通的方法,都是以
self作為第一個參數,代表著通過執行個體調用時,將執行個體的範圍傳入方法內;
@classmethod以cls作為第一個參數,代表將類本身的範圍傳入。無論通過類來調用,還是通過類的執行個體調用,預設傳入的第一個參數都將是類本身
@staticmethod不需要傳入預設參數,類似於一個普通的函數
執行個體方法隱含的參數為類執行個體self;
類方法隱含的參數為類本身cls;
靜態方法無隱含參數,主要為了類執行個體也可以直接調用靜態方法。
邏輯上類方法應當只被類調用,執行個體方法執行個體調用,靜態方法兩者都能調用。
而實際上,python實現了一定的靈活性使得類方法和靜態方法都能夠被執行個體和類二者調用。
皮皮blog
樣本樣本1
#!/usr/bin/env python# -*- coding: utf-8 -*-"""__title__ = ‘python執行個體方法,類方法和靜態方法區別及使用‘__author__ = ‘皮‘__email__ = ‘[email protected]‘# code is far away from bugs with the god animal protecting I love animals. They taste delicious."""import tracebackclass T: def InstanceMethod(self): print("instance Method!") print(self) @classmethod def ClassMethod(cls): # def ClassMethod(self):#當然這樣也不會出錯 print("class Method") print(cls) @staticmethod def StaticMethod(): print("static method")t = T()t.InstanceMethod()t.ClassMethod()t.StaticMethod()T.ClassMethod()T.StaticMethod()T.InstanceMethod(t)# 錯誤的情況try: t.ClassMethod(T) T.InstanceMethod()except: print(traceback.format_exc())
樣本2
假設我們需要建立一個名為Date的類,用於儲存 年/月/日 三個資料
class Date(object):
def __init__(self, year=0, month=0, day=0):
self.year = year
self.month = month
self.day = day
@property
def time(self):
return "{year}-{month}-{day}".format(
year=self.year,
month=self.month,
day=self.day
)
上述代碼建立了Date類,該類會在初始化時設定day/month/year屬性,並且通過property設定了一個getter,可以在執行個體化之後,通過time擷取儲存的時間:
date = Date(‘2016‘, ‘11‘, ‘09‘)
date.time # 2016-11-09
但如果我們想改變屬性傳入的方式呢?畢竟,在初始化時就要傳入年/月/日三個屬性還是很煩人的。能否找到一個方法,在不改變現有介面和方法的情況下,可以通過傳入2016-11-09這樣的字串來建立一個Date執行個體?
你可能會想到這樣的方法:
date_string = ‘2016-11-09‘
year, month, day = map(str, date_string.split(‘-‘))
date = Date(year, month, day)
但不夠好:
在類外額外多寫了一個方法,每次還得格式化以後擷取參數
這個方法也只跟Date類有關
沒有解決傳入參數過多的問題
此時就可以利用@classmethod,在類的內部建立一個格式化字串,並返回類的執行個體的方法:
# 在 Date 內新增一個 classmethod
@classmethod
def from_string(cls, string):
year, month, day = map(str, string.split(‘-‘))
# 在 classmethod 內可以通過 cls 來調用到類的方法,甚至建立執行個體
date = cls(year, month, day)
return date
這樣,我們就可以通過Date類來調用from_string方法建立執行個體,並且不侵略、修改舊的執行個體化方式:
date = Date.from_string(‘2016-11-09‘)
# 舊的執行個體化方式仍可以使用
date_old = Date(‘2016‘, ‘11‘, ‘09‘)
好處:
在@classmethod內,可以通過cls參數,擷取到跟外部調用類時一樣的便利
可以在其中進一步封裝該方法,提高複用性
更加符合物件導向的編程方式
而@staticmethod,因為其本身類似於普通的函數,所以可以把和這個類相關的 helper 方法作為@staticmethod,放在類裡,然後直接通過類來調用這個方法。
# 在 Date 內新增一個 staticmethod
@staticmethod
def is_month_validate(month):
return int(month) <= 12 and int(month) >= 1
將與日期相關的輔助類函數作為@staticmethod方法放在Date類內後,可以通過類來調用這些方法:
month = ‘08‘
if not Date.is_month_validate(month):
print(‘{} is a validate month number‘.format(month))
from:http://blog.csdn.net/pipisorry/article/details/49516185
ref: [Static Methods and Class Methods?]*
python類:class
[Python @classmethod and @staticmethod for beginner]
[Difference between staticmethod and classmethod in python]
python類:類方法和靜態方法