(2022.02.15 Tues)
Python類自帶了三個(gè)裝飾器嗓节。被@classmethod
裝飾的方法是類方法,被@staticmethod
裝飾的方法是靜態(tài)方法帕膜,沒有裝飾器的方法是實(shí)例方法枣氧。
@classmethod 類方法
該裝飾器用于修飾類的方法中的類方法,該方法不因?qū)嵗淖儭?br> 調(diào)用方式:
-
class_name.method_name
:在調(diào)用經(jīng)@classmethod
修飾的類方法時(shí)不需要實(shí)例化類垮刹。 -
instance_name.method_name
:也可在實(shí)例化之后通過實(shí)例化的類名加方法名來調(diào)用达吞。
類方法定義不需要指定self
作為輸入?yún)?shù),但第一個(gè)傳遞的參數(shù)必須是自身類的cls
荒典,可用來調(diào)用類的方法酪劫,實(shí)例化對(duì)象等吞鸭。可以返回一個(gè)類覆糟。定義格式如
class A:
@classmethod
def func(cls, args1, args2, ...):
pass
該裝飾器的優(yōu)勢在于刻剥,當(dāng)重構(gòu)類的時(shí)候不需要修改構(gòu)造函數(shù),只需要添加新的方法滩字,并用@classmethod
裝飾即可透敌。
# 初始類
class Data_test(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, ", month: ", self.month, ", day: ", self.day)
# 新增
class Str2IntParam(Data_test):
@classmethod
def get_date(cls, string_date):
#這里第一個(gè)參數(shù)是cls, 表示調(diào)用當(dāng)前的類名
year, month, day = map(int, string_date.split('-'))
date1 = cls(year, month, day)
#返回的是一個(gè)初始化后的類
return date1
$ r = Str2IntParam.get_date("2016-8-1")
$ r.out_date()
year: 2016, month: 8, day: 1
被@classmethod
修飾的類方法可修改類的狀態(tài)踢械,并應(yīng)用于類的所有對(duì)象,比如可通過類方法修改類變量并應(yīng)用于類的所有對(duì)象魄藕。It would modify the class state that would apply across all the instances of the class. For example, it can modify a class variable that would be applicable to all the instances.
(2022.02.21 Mon)
在下面這個(gè)例子中内列,類方法用于在每次類實(shí)例化時(shí)更新類變量cntr
。注意查看每次實(shí)例化之前和之后類變量的值背率。
class DemoClass:
cntr = 0
def __init__(self, name):
self.name = name
self.cntr = self.cntr_number()
@classmethod
def cntr_number(cls):
cls.cntr += 1
return cls.cntr
>>> DemoClass.cntr
0
>>> a = DemoClass(1)
>>> DemoClass.cntr
1
>>> b = DemoClass(2)
>>> DemoClass.cntr
2
>>> a.cntr
1
上面的演示說明類方法的使用使得類具有記憶力话瞧。這個(gè)特性可應(yīng)用于深度學(xué)習(xí)的模型訓(xùn)練。
Python不支持類似于C++/Java中的方法重載(method overloading)寝姿,于是使用@classmethod
修飾的類方法創(chuàng)建工廠方法(factory method)交排。在不同的案例中,工廠方式可以返回類對(duì)象饵筑,就像一個(gè)構(gòu)造函數(shù)(constructor)埃篓。
@staticmethod 靜態(tài)方法
(2022.02.16 Wed)
該指令修飾靜態(tài)方法。靜態(tài)方法的輸入?yún)?shù)沒有要求根资,不需要傳入類方法的cls
作為輸入?yún)?shù)架专,也不需要傳入實(shí)例方法中的self
作為輸入?yún)?shù),傳入?yún)?shù)可以任意指定玄帕。
調(diào)用方式:
class_name.method_name
-
instance_name.method_name
部脚,在實(shí)例化后。
靜態(tài)方法不改變類的行為和狀態(tài)裤纹,靜態(tài)方法不需要類本身作為一個(gè)輸入?yún)?shù)委刘,靜態(tài)方法甚至可以放在類之外單獨(dú)定義。在Python提出類的設(shè)計(jì)之前鹰椒,通常在全局namespace中創(chuàng)建函數(shù)锡移。類中加入靜態(tài)方法很多時(shí)候是方便類的使用(?)使用靜態(tài)方法甚至有時(shí)是糟糕設(shè)計(jì)的標(biāo)志。
import time
class ClassA:
def __init__(self):
pass
@staticmethod
def show_time():
print(time.perf_time())
@property property方法
(2022.02.21 Mon)
@property
裝飾器將方法轉(zhuǎn)換為同名的屬性吹零,即調(diào)用該方法時(shí)不加擴(kuò)號(hào)罩抗,將方法當(dāng)成一個(gè)只讀屬性來調(diào)用。配合所定義的屬性灿椅,可以防止對(duì)屬性的修改套蒂。
class demoClass:
@property
def attr(self):
return '99g1'
def no_property(self):
return '99g1aswell'
實(shí)例化并調(diào)用的結(jié)果如下
>>> a.attr
'99g1'
>>> a.attr()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> a.no_property()
'99g1aswell'
>>> a.no_property
<bound method demoClass.no_property of <__main__.demoClass object at 0x10f0de370>>
Python中無法設(shè)置私有屬性钞支,卻可通過@property
來設(shè)置私有屬性,隱藏屬性名操刀,使得用戶無法修改烁挟。
class dataSet:
def __init__(self):
self._var1 = 1
self._var2 = 2
@property
def var1(self):
return self._var1
@property
def var2(self):
return self._var2
調(diào)用如下
>>> c = dataSet()
>>> c.var1
1
>>> c._var1
1
>>> c.var2
2
>>> c._var2
2
(2022.02.22 Tues)
下面通過一個(gè)例子演示類的繼承過程中,子類對(duì)父類中不同方法的繼承方式骨坑。
class allMethod:
x = 1
y = 2
@classmethod
def classm(cls):
return cls.x + cls.y
@staticmethod
def staticm():
return allMethod.x + allMethod.y
@property
def propertym(self):
return self.x
class testClass(allMethod):
x = 7
y = 5
實(shí)例化子類
>>> d = testClass()
>>> d.classm()
12
>>> d.staticm()
3
>>> d.propertym
7
對(duì)子類實(shí)例化之后撼嗓,我們看到
-
@classmethod
類方法:實(shí)例中的類方法調(diào)用的是子類的方法和子類的屬性。因類方法傳遞的參數(shù)是cls
欢唾,即子類本身且警。 -
@staticmethod
靜態(tài)方法:實(shí)例中的靜態(tài)方法調(diào)用的父類的方法和父類的屬性。因靜態(tài)方法傳遞的參數(shù)是原始類名(父類名)礁遣。 -
@property
property方法:實(shí)例中的property方法調(diào)用的子類的屬性斑芜。因property方法傳遞的參數(shù)是self
,即子類對(duì)象祟霍。