https://www.cnblogs.com/Keep-Ambition/p/7296492.html
裝飾器方法
類的另外的特性,裝飾器方法:靜態方法(staticmethod)、類方法(classmethod)、屬性方法(property)
一、靜態方法
在方法名前加上@staticmethod裝飾器,表示此方法為靜態方法

class Dog(object): def __init__(self,name): self.name = name @staticmethod #在方法前加上staticmethod 裝飾器定義靜態方法 def eat(): print("dog is eating"
靜態方法特性
特性:只是名義上歸類管理,實際上在靜態方法里訪問不了類或實例中的任何屬性
1、靜態方法,是不可以傳入self參數的,但是想傳也可以,調用時必須傳入實例本身

class Dog(object): def __init__(self,name): self.name = name @staticmethod #定義靜態方法 def eat(self,food): #可以定義,但是需傳入實例本身 print("{0} is eating {1}".format(self.name,food)) d = Dog("shabi") d.eat(d,"hotdog") #傳入實例d本身,否則會報錯 #輸出 shabi is eating hotdog
2、靜態方法可以用類直接調用,直接調用時,不可以直接傳入self,否則會報錯

class Dog(object): def __init__(self,name): self.name = name @staticmethod def eat(food): print("is eating {0}".format(food)) Dog.eat("hotdog") #輸出 is eating hotdog
3、靜態方法的使用場景,這種場景挺常見,就像os模塊的中某些函數一樣,都是使用了靜態方法

import os os.system() os.mkdir()
二、類方法
在方法名前加上@classmethod裝飾器,表示此方法為類方法

class Dog(object): name = "honggege" #定義靜態屬性 def __init__(self,name): self.name = name @classmethod #定義類方法 def eat(self,food): print("{0} is eating {1}".format(self.name,food))
類方法特性
特性:只能訪問類變量(又叫靜態屬性),不能訪問實例變量
1、訪問實例變量

class Dog(object): def __init__(self,name): self.name = name @classmethod #定義類方法 def eat(self,food): print("{0} is eating {1}".format(self.name,food)) d = Dog("shabihong") d.eat("hotdog") #輸出 File "D:/PycharmProjects/pyhomework/day7/類方法.py", line 11, in <module> d.eat("hotdog") File "D:/PycharmProjects/pyhomework/day7/類方法.py", line 8, in eat print("{0} is eating {1}".format(self.name,food)) AttributeError: type object 'Dog' has no attribute 'name'
2、訪問類變量(又叫靜態屬性)

class Dog(object): name = "honggege" #定義類變量 def __init__(self,name): self.name = name @classmethod def eat(self,food): print("{0} is eating {1}".format(self.name,food)) d = Dog("shabihong") d.eat("hotdog") #輸出 honggege is eating hotdog #調用的是類變量
3、使用場景:一般是需要去訪問寫死的變量,才會用到類方法裝飾器
三、屬性方法
在方法名前加上@property裝飾器,表示此方法為屬性方法

class Dog(object): def __init__(self,name): self.name = name @property #定義屬性方法 def eat(self): print("{0} is eating".format(self.name))
屬性方法特性
特性:把一個方法變成一個靜態屬性
1、靜態屬性的調用

class Dog(object): def __init__(self,name): self.name = name @property #定義屬性方法 def eat(self): print("{0} is eating".format(self.name)) d = Dog("shabihong") d.eat #把方法變成靜態屬性調用 #輸出 shabihong is eating
2、給轉成的靜態屬性賦值
用@靜態方法名.setter(屬性裝飾器)去裝飾方法,來給轉換后的靜態屬性賦值

上面代碼沒有把food傳上去,那是因為傳參方法,沒有把接收之前的food的賦值,修改成如下代碼就能成功上傳:

3、刪除轉變的靜態屬性
用@靜態方法名.deleter(屬性裝飾器)去裝飾,表明可以刪除轉化后的靜態屬性

4、靜態屬性使用場景
一個航班當前的狀態,是到達了、延遲了、取消了、還是已經飛走了, 想知道這種狀態必須經歷以下幾步:
1. 連接航空公司API查詢
2. 對查詢結果進行解析
3. 返回結果給你的用戶
因此這個status屬性的值是一系列動作后才得到的結果,所以你每次調用時,其實它都要經過一系列的動作才返回你結果,但這些動作過程不需要用戶關心, 用戶只需要調用這個屬性就可以

class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later") @flight_status.setter #修改 def flight_status(self,status): status_dic = { 0 : "canceled", 1 :"arrived", 2 : "departured" } print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) ) @flight_status.deleter #刪除 def flight_status(self): print("status got removed...") f = Flight("CA980") f.flight_status f.flight_status = 2 #觸發@flight_status.setter del f.flight_status #觸發@flight_status.deleter
裝飾器方法總結:
- 靜態方法是訪問不了類或實例中的任何屬性,它已經脫離了類,一般會用在一些工具包中
- 類方法,只能訪問類變量,不能訪問實例變量
- 屬性方法是把一個方法變成一個靜態屬性
類的特殊成員方法
類的方法,有普通方法,就是我們自己定義的方法,還有裝飾器方法(靜態方法,類方法,屬性方法),其實類還有另外一種方法,叫做類的特殊成員方法
1、 __doc__
說明:表示類的描述信息
1
2
3
4
5
6
7
8
9
10
11
|
class
Dog(
object
):
"""此類是形容Dog這個類"""
#類的描述信息
def
__init__(
self
,name):
self
.name
=
name
print
(Dog.__doc__)
#打印類的描述信息
#輸出
此類是形容Dog這個類
|
2、 __module__和__class__
說明:
- __module__: 表示當前操作的對象在哪個模塊
- __class__:表示當前操作的對象的類是什么
aa.py的代碼:
1
2
3
4
|
class
C(
object
):
def
__init__(
self
):
self
.name
=
"shuaigaogao"
|
index.py的代碼:
1
2
3
4
5
6
7
8
9
10
|
from
lib.aa
import
C
obj
=
C()
print
(obj.__module__)
#表示當前操作的對象在哪個模塊
print
(obj.__class__)
#表示當前操作的對象的類是什么
#輸出
lib.aa
<
class
'lib.aa.C'
>
|
3 、__init__
說明:構造方法,通過類創建對象時,自動觸發執行
4、 __del__
說明:析構方法,當對象在內存中被釋放時,自動觸發執行
注:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執行,
所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的
5、 __call__
說明: 對象后面加括號,觸發執行
1
2
3
4
5
6
7
8
9
10
11
12
|
class
Foo(
object
):
def
__init__(
self
):
self
.name
=
"shuaigaogao"
def
__call__(
self
,
*
args,
*
*
kwargs):
#重寫call方法
print
(
"running call"
,args,kwargs)
f
=
Foo()
#執行__init__
f(
1
,
2
,
3
,name
=
333
)
# 執行call方法,也可以寫成 Foo()(1,2,3,name=333)
#輸出
running call (
1
,
2
,
3
) {
'name'
:
333
}
|
注:構造方法的執行是由創建對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象后加括號觸發的,即:對象() 或者 類()()
6 、__dict__
說明: 查看類或對象中的所有成員
①類.__dict__
效果:打印類中所有的屬性,不包括實例屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class
Province(
object
):
country
=
'China'
def
__init__(
self
, name, count):
self
.name
=
name
self
.count
=
count
def
func(
self
,
*
args,
*
*
kwargs):
print
(
"func"
)
print
(Province.__dict__)
#類.__dict__
#輸出
{
'__doc__'
:
None
,
'__weakref__'
: <attribute
'__weakref__'
of
'Province'
objects>,
'__init__'
:
<function Province.__init__ at
0x00000247F3CAD488
>,
'country'
:
'China'
,
'__dict__'
:
<attribute
'__dict__'
of
'Province'
objects>,
'func'
: <function Province.func at
0x00000247F3CAD510
>,
'__module__'
:
'__main__'
}
#打印類中所有的屬性,不包括實例屬性
|
②實例名.__dict__
效果:打印該實例的所有屬性,不包括類屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
Province(
object
):
country
=
'China'
def
__init__(
self
, name, count):
self
.name
=
name
self
.count
=
count
def
func(
self
,
*
args,
*
*
kwargs):
print
(
"func"
)
p
=
Province(
"jiangsu"
,
20000
)
#實例化
print
(p.__dict__)
#實例名.__dict__
#輸出
{
'count'
:
20000
,
'name'
:
'jiangsu'
}
#打印該實例的所有屬性,不包括類屬性
|
7 、__str__
說明:如果一個類中定義了__str__方法,那么在打印 對象 時,默認輸出該方法的返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
Province(
object
):
country
=
'China'
def
__init__(
self
, name):
self
.name
=
name
def
__str__(
self
):
return
"<obj:{0}>"
.
format
(
self
.name)
p
=
Province(
"jiangsu"
)
print
(p)
#打印這個對象
#輸出
<obj:jiangsu>
#給對象重新起了一個名字
|
注:這個以后會在django框架里面會用到,這邊就不多說了
8 、__getitem__、__setitem__、__delitem__
說明:用於索引操作,如字典。以上分別表示獲取、設置、刪除數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class
Foo(
object
):
def
__getitem__(
self
, key):
print
(
'__getitem__:'
,key)
def
__setitem__(
self
, key, value):
print
(
'__setitem__:'
,key,value)
def
__delitem__(
self
, key):
print
(
'__delitem__'
,key)
f
=
Foo()
f[
"name"
]
=
"shuaigaogao"
#自動觸發__setitem__方法
f[
"name"
]
#自動觸發__getitem__方法
del
f[
"name"
]
#自動觸發__delitem__方法
#輸出
__setitem__: name shuaigaogao
__getitem__: name
__delitem__ name
|
注:這邊的__delitem__沒有做真正的刪除,只是觸發這個方法,想要真正刪除,只需要在__delitem__函數中添加刪除功能即可