日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

python中的classmethod與staticmethod_python

作者:咕嘟咕嘟_ ? 更新時間: 2022-03-29 編程語言

1.靜態方法(staticmethod)

靜態方法:

@staticmethod也是一個類方法,是可以直接類調用的。個人認為的使用場景是:只要要定義的方法里不涉及到self參數,就用靜態方法承擔。因為這樣就表明這個方法和本身的類沒有關系,明確的區別出類相關和不相關。

class A:
? ? def __init__(self, a, b):
? ? ? ? self.a = a
? ? ? ? self.b = b

? ? def do_normal_something(self, a, b):
? ? ? ? print("do_normal_something",a,b)

? ? @staticmethod
? ? def do_static_something(a,b):
? ? ? ? print('do_static_something',a,b)

? ? @classmethod
? ? def do_class_something(cls):
? ? ? ? pass

? ? def __call__(self,a,b):
? ? ? ? print("123call",a,b)

a = A(1,2)
a.do_normal_something(7,8)
a.do_static_something(5,6)

2.類方法(classmethod)

為什么會出現classmethod

classmethod設計的目的是什么呢?事實上與Python面向對象編程有關的,由于Python不支持多個的參數重載構造函數,比方在C++里,構造函數能夠依據參數個數不一樣。能夠寫多個構造函數。Python為了解決問題,採用classmethod修飾符的方式,這樣定義出來的函數就能夠在類對象實例化之前調用這些函數,就相當于多個構造函數,解決多個構造函數的代碼寫在類外面的問題。

  • 類最基本的作用是實例化出一個對象,但是有的時候在實例化之前,就需要先和類做一定的交互,這種交互可能會影響實際實例化的過程,所以必須放在調用構造函數之前。大概也可能是因為這個原因出現了classmethod
  • 直接一點來說,我們知道對于一個普通的類,我們要使用其中的方法的話,需要對類進行實例化,而一個類中,某個函數前面加上了staticmethod或者classmethod的話,那么這個函數就可以不通過實例化直接調用,可以通過類名進行調用的
  • @classmethod 定義的類方法是可選構造函數中,我們定義了一個類方法,類方法的第一個參數(cls)指代的就是類本身。類方法會用這個類來創建并返回最終的實例。使用類方法的另一個好處就是在繼承的時候,保證了子類使用可選構造函數構造出來的類是子類的實例而不是父類的實例。

案例:

class Data_test(object):

? ? 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,'month:',self.month,'day:',self.day)

t = Data_test(2016, 8, 1)
t.out_date()

但是如果用戶輸入的是 “2016-8-1” 這樣的字符格式,那么就需要調用Date_test 類前做一下處理:

class Data_test(object):

? ? 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,'month:',self.month,'day:',self.day)


string_date = '2016-8-1'
year, month, day = map(int, string_date.split('-'))
s = Data_test(year, month, day)
s.out_date()

先把‘2016-8-1’ 分解成 year,month,day 三個變量,然后轉成int,再調用Date_test(year,month,day)函數。 也很符合期望。

那我可不可以把這個字符串處理的函數放到 Date_test 類當中呢?

那么@classmethod 就開始出場了

class Data_test(object):

? ? def __init__(self, year=0, month=0, day=0):
? ? ? ? self.day = day
? ? ? ? self.month = month
? ? ? ? self.year = year

? ? @classmethod
? ? def getdata(cls,str): #cls表示調用當前類名
? ? ? ? year, month, day = map(int, string_date.split('-'))
? ? ? ? s = cls(year,month,day)
? ? ? ? return s #返回一個初始化的類

? ? def out_date(self):
? ? ? ? print('year:',self.year,'month:',self.month,'day:',self.day)


string_date = '2016-8-1'
s = Data_test.getdata(string_date)
s.out_date()

在繼承時也能工作的很好:

類方法的一個主要用途就是定義多個構造器。它接受一個class 作為第一個參數(cls)。在繼承時也能工作的很好:

import time

class Data:
? ? #主要構造器
? ? def __init__(self,y,m,d):
? ? ? ? self.year = y
? ? ? ? self.month = m
? ? ? ? self.day = d
? ? ? ? print('year:', self.year, 'month:', self.month, 'day:', self.day)
? ? # 可選擇的構造器
? ? @classmethod
? ? def today(cls):
? ? ? ? t = time.localtime()
? ? ? ? return cls(t.tm_year,t.tm_mon,t.tm_mday)

a = Data(2022,1,13) #主要構造器
b = Data.today() #可選擇的構造器

class NewData(Data):
? ? pass
c = NewData.today() #繼承的時候也可照樣工作

原文鏈接:https://blog.csdn.net/EMIvv/article/details/122482756

欄目分類
最近更新