前言
python 類里面常用的方法有3個:靜態方法(@staticmethod),類方法(@classmethod)和實例方法(self)。
函數
方法跟函數是有區別的,函數定義是def 關鍵字定義(外面沒class)。
def fun(): a = "hello" return a # 函數調用 res = fun() print(res)
函數調用使用函數名稱后面加括號就能調用了
實例方法(self)
類里面的方法定義也是用def 關鍵字,注意在類里面叫方法了,不叫函數,定義的方法默認在括號里面加一個self參數。
self 是類本身的實例對象,所以在看到def 定義的方法括號后面有self參數的叫實例方法。
class A(object): count = 0 def fun(self): b = "world" return b # A類不能直接調用fun # print(A.fun()) a = A() print(a.fun())
靜態方法(@staticmethod)
我們可以在函數里面寫一個類:
def fun(): a = "hello" class A(object): count = 0 def fun(self): b = "world" return b return A
於是會想到,在類里面是不是也可以寫一個函數呢?【類里面寫函數,注意不是方法】於是就有了靜態方法(@staticmethod),靜態方法的出現就是為了在類里面可以寫一個函數,當普通的函數去調用。
定義靜態方法需使用@staticmethod裝飾器,並且括號后面不需要self參數了。
class A(object): count = 0 def fun(self): b = "world" return b @staticmethod def start(): print("start-----") # 不用實例化也能調用 A.start() # 實例化也能調用 a = A() a.start()
靜態方法不需要實例化可以直接調用,實例化后也能調用,可以理解成函數。
類方法(@classmethod)
類里面有2個概念,屬性和方法。
既然已經知道了A類的屬性和A()實例對象屬性是不一樣的,再回到前面的實例方法概念上,實例方法是A()實例對象的方法。
既然A()實例對象有實例方法,那么A類當然也有類方法的概念了,於是可以在方法上加上@classmethod裝飾器聲明它是類方法,並且括號第一個參數cls是指類本身。
class A(object): count = 0 def fun(self): b = "world" return b @staticmethod def start(): print("start-----") @classmethod def create(cls): print("create--------") # 不需要實例化,類名稱直接調用類方法 A.create() # 實例化也能調用類方法 a = A() a.create()
類方法使用場景
實例方法和靜態方法小伙伴們應該是經常用的,類方法這個概念本身比較難懂,就算看懂了也不知道如何用到具體場景上,在網上搜到一個案例講解的挺好的。
class DataTest(object): day = 0 month = 0 year = 0 def __init__(self, year=0, month=0, day=0): self.day = day self.month = month self.year = year def out_date(self): print("year :", self.year) print("month :", self.month) print("day :", self.day) t = DataTest(2021, 8, 18) t.out_date()
運行結果:
year : 2021 month : 8 day : 18
但是如果用戶輸入的是 "2016-8-1" 這樣的字符格式,那么就需要調用Date_test 類前做一下處理:
string_date = '2018-8-18' year, month, day = map(int, string_date.split('-')) s = DataTest(year, month, day) print(s.out_date())
先把‘2018-8-18’ 分解成 year,month,day三個變量,然后轉成int,再調用DataTest(year, month, day) 也很符合期望。
那我可不可以把這個字符串處理的函數放到 DateTest 類當中呢?
那么@classmethod 就開始出場了:【類最基本的作用是實例化出一個對象,但是有的時候再實例化之前,就需要先和類做一定的交互,這種交互可能會影響實際實例化的過程,所以必須放在調用構造函數之前。】
class DataTest(object): day = 0 month = 0 year = 0 def __init__(self, year=0, month=0, day=0): self.day = day self.month = month self.year = year def out_date(self): print("year :", self.year) print("month :", self.month) print("day :", self.day) @classmethod def get_data(cls, string_date): """處理'2018-8-18'字符格式""" year, month, day = map(int, string_date.split('-')) return cls(year, month, day)
定義一個get_data類方法,處理完字符串后返回這個類的實例對象:【與實例化類返回類的實例對象的作用相同】
r = DataTest.get_data('2018-8-18') r.out_date()
這樣同樣可以達到實例化的效果,於是就兼容了前面的代碼了。