Python類中裝飾器classmethod,staticmethod,property,

@classmethod

有的時候在類中會有一種狀況,就是這個方法並不須要使用每個對象屬性
所以 這個方法中的self參數一個徹底無用的參數,使用classmethodpython

class A:
    __count = 0  # 隱藏類count屬性

    def __init__(self, name):
        self.name = name
        self.__add_count()  # 每一次實例化的時候掉
        # 用私有方法來對__count 進行累加

    @classmethod
    def __add_count(cls):  # 定義一個私有方法
        print(cls, A)
        A.__count += 1  # 讓這個方法只能在類的內部被使用

    @classmethod
    def show_count(cls):  # 被classmethod 裝飾去的方法,
        print(cls.__count)
        return A.__count  # 讓用戶能夠從外部查看__count的值

    def show_count_self(self):  # 定義一個普通方法
        # print(self.__count)
        print(self)
        # print('_____')
        # print(self.show_count(),'fogogo')
        # return A.__count  # 讓用戶能夠從外部查看__count的值


# show_count 是一個查看類中屬性的方法,這樣的方法和某一個對象並無直接聯繫        
        


obj = A('baozi')
print(A._A__add_count) # 
# 執行結果
<class '__main__.A'> <class '__main__.A'>
<bound method A.__add_count of <class '__main__.A'>>

本質上 :函數

@classmethodcode

一個方法不用對象屬性可是使用靜態屬性 -- 類方法@classmethod
某一個方法被創造出來,就是爲了進行對靜態變量進行操做對象

@staticmehtodget

根本不涉及到對象,因此這個方法就應該被定義成 類方法(被@classmethod裝飾)
調用這個類方法,可使用對象調用,也可使用類調用
可是這個方法的默認參數永遠是當前類的命名空間,而不是對象的it

@staticmethod

若是一個類中的方法不用 對象屬性 也不用 靜態屬性 -- 靜態方法@staticmethodtable

那實際上這個方法就是一個普通的函數class

class User(object):

    @staticmethod
    def login(arg1, arg2):#是User類中的名字函數的名字login就是一個類中的靜態方法,本質上就是一個函數
        return (arg1 + arg2)


    def show(self):
        print('---->show')
        print('---self--',self.login(1, 3))
        print('class--',User.login(123, 31))


print(User.login(1,2)) ## 不須要實例化,當函數使用
print(User().show())

# 執行結果

3
---->show
---self-- 4
class-- 154

一個不須要用到對象命名空間中的變量方法,就不是一個對象方法,就應該是一個普通的函數變量

方法的查找的順序:

  • 是直接在本身的空間找到類 類這個方法object

  • 對象先在本身的空間找,找不到,就到類的空間

classmethod staticmethod 使用場景說明:

用哪個命名空間的名字,就定義的不一樣的方法
  1. self 只要用self 就是普通方法,只能用對象調

  2. Classmethod 只要cls 就是類方法,能夠用類,能夠用對象

  3. Staticmethod 啥用不用 就是靜態方法 ,能夠用,能夠用對象

普通的方法 類方法 靜態方法
默認參數 self cls
操做變量 操做對象屬性 操做靜態屬性 既不操做對象屬性,也不操做類的屬性
所屬的命名空間
調用方式 對象 類/對象 類/對象
對應的裝飾器 @classmethod @staticmethod

@property

把一個方法假裝成屬性,

下面例子中計算圓面積的公式

class Cirecle:
    def __init__(self, r):
        self.r = r

    @property
    def area(self):  # 被property 裝飾器 裝飾的方法不能傳遞 除self之外參數

        return pi * self.r ** 2

    def perimeter(self):
        return self.r * pi * 2


c1 = Cirecle(5)

print(c1.area)
# 打印執行結果

78.53981633974483

某一個屬性須要被私有,可是有須要能夠被外部查看, 這種狀況,把這個屬性經過方法,`property 假裝成屬性

class Person:

    def __init__(self, name):
        self.__name = name  # 不讓外面隨便修改

    @property
    def get_name(self):
        return self.__name


ari = Person('arimiage')

print(ari.get_name)
# 執行結果

arimiage

Property 修改屬性值

  • @funcname.setter
  • @funcname.deleter
class Person:

    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter  # 只能傳一個參數。以前必須有一個同名的方法被property裝飾過
    def name(self, new_name):
        if isinstance(new_name, str):
            # if type(new_name) is str:
            self.__name = new_name
            #setattr裝飾的函數名叫什麼
            #那麼這個函數中絕對不能夠對這個,函數名同名屬性進行修改( 函數名)

    @name.deleter
    def name(self):
        print('gogoog')
        del self.__name #這裏才執行刪除屬性操做

    def get_name(self):
        return self.__name

    # def set_name(self,new_name):
    # if type(new_name) is str:
    # if isinstance(new_name,str):
    #     self.__name == new_name

    

ari = Person('arimiage')
{'_Person__name': 'arimiage'}
# print(Person.__dict__)

print(ari.get_name)

ari.name = 'fgo'
{'_Person__name': 'fgo'} #對象空間
print(Person.__dict__)
print(ari.__dict__)
print(ari.name)

del ari.name # 只是至關於調用被deleter裝飾的方法,並不至關於刪除name屬性
{} 對象空間爲空

# print(ari.__dict__)  # 報錯
相關文章
相關標籤/搜索