【python】-- 類的裝飾器方法、特殊成員方法


裝飾器方法

類的另外的特性,裝飾器方法:靜態方法(staticmethod)、類方法(classmethod)、屬性方法(property)

 

一、靜態方法

在方法名前加上@staticmethod裝飾器,表示此方法為靜態方法

class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    @staticmethod  #在方法前加上staticmethod 裝飾器定義靜態方法
    def eat():
        print("dog is eating"
View Code

靜態方法特性

特性:只是名義上歸類管理,實際上在靜態方法里訪問不了類或實例中的任何屬性

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
View Code

 

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
View Code

 

 3、靜態方法的使用場景,這種場景挺常見,就像os模塊的中某些函數一樣,都是使用了靜態方法

import os
 
os.system()
os.mkdir()
View Code

 

 

 二、類方法

在方法名前加上@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))
View Code

 類方法特性

特性:只能訪問類變量(又叫靜態屬性),不能訪問實例變量

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'
View Code

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  #調用的是類變量
View Code

3、使用場景:一般是需要去訪問寫死的變量,才會用到類方法裝飾器

 

 

三、屬性方法

在方法名前加上@property裝飾器,表示此方法為屬性方法

class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    @property  #定義屬性方法
    def eat(self):
        print("{0} is eating".format(self.name))
View Code

屬性方法特性

特性:把一個方法變成一個靜態屬性

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
View Code

 2、給轉成的靜態屬性賦值

 用@靜態方法名.setter(屬性裝飾器)去裝飾方法,來給轉換后的靜態屬性賦值

class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    @property   #定義屬性方法
    def eat(self):
        print("{0} is eating {1}".format(self.name,"honggege"))
 
    @eat.setter  #定義一個可以傳參的方法
    def eat(self,food):
        print("set to food:",food)
        # self.__food = food
 
d = Dog("shabihong")
d.eat = "hotdog"  #給轉成的靜態變量賦值
d.eat
 
#輸出
set to food: hotdog
shabihong is eating honggege
View Code

 

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

class Dog(object):
 
    def __init__(self,name):
        self.name = name
        self.__food = None
 
    @property   #定義屬性方法
    def eat(self):
        print("{0} is eating {1}".format(self.name,self.__food))
 
    @eat.setter  #定義可以設置變量賦值
    def eat(self,food):
        print("set to food:",food)
        self.__food = food
 
d = Dog("shabihong")
d.eat      #第一份賦值的是None
d.eat = "hotdog"
d.eat    #第二個賦值是hotdog
 
#輸出
shabihong is eating None
set to food: hotdog
shabihong is eating hotdog   #說明賦值成功
View Code

 

3、刪除轉變的靜態屬性

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

class Dog(object):
 
    def __init__(self,name):
        self.name = name
        self.__food = None
 
    @property
    def eat(self):
        print("{0} is eating {1}".format(self.name,self.__food))
 
    @eat.setter
    def eat(self,food):
        print("set to food:",food)
        self.__food = food
 
    @eat.deleter   #定義可以刪除eat這個靜態屬性
    def eat(self):
        del self.__food
        print("food 變量刪除完畢")
 
d = Dog("shabihong")
del d.eat  #刪除靜態屬性eat
 
#輸出
food 變量刪除完畢
View Code

 

 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
View Code

 

 

 

裝飾器方法總結:

  1. 靜態方法是訪問不了類或實例中的任何屬性,它已經脫離了類,一般會用在一些工具包中
  2. 類方法,只能訪問類變量,不能訪問實例變量
  3. 屬性方法是把一個方法變成一個靜態屬性

 

 

 

類的特殊成員方法

類的方法,有普通方法,就是我們自己定義的方法,還有裝飾器方法(靜態方法,類方法,屬性方法),其實類還有另外一種方法,叫做類的特殊成員方法

1、 __doc__

說明:表示類的描述信息

class Dog(object):
    """此類是形容Dog這個類"""    #類的描述信息
 
    def __init__(self,name):
        self.name = name
 
 
print(Dog.__doc__)   #打印類的描述信息
 
#輸出
此類是形容Dog這個類

2、 __module__和__class__

說明:

  1. __module__: 表示當前操作的對象在哪個模塊
  2. __class__:表示當前操作的對象的類是什么

aa.py的代碼:

class C(object):
 
    def __init__(self):
        self.name = "shuaigaogao"

index.py的代碼:

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__

說明: 對象后面加括號,觸發執行

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__

效果:打印類中所有的屬性,不包括實例屬性

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__

效果:打印該實例的所有屬性,不包括類屬性

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__方法,那么在打印 對象 時,默認輸出該方法的返回值

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__

說明:用於索引操作,如字典。以上分別表示獲取、設置、刪除數據

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__函數中添加刪除功能即可

9、__new__ \ __metaclass__

 詳細說明:點擊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM