測開之函數進階· 第8篇《多個裝飾器裝飾同一個函數,三個內置的裝飾器》

堅持原創輸出,點擊藍字關注我吧

作者:清菡
博客:oschina、雲+社區、知乎等各大平台都有。

由於微信公眾號推送改為了信息流的形式,防止走丟,請給加個星標 ⭐,你就可以第一時間接收到本公眾號的推送!

目錄

  • 一、多個裝飾器裝飾同一個函數
  • 二、Python 中類裏面三個內置的裝飾器
    • 1.@classmethod
    • 2.@staticmethod
    • 3.@property
  • 三、3個內置裝飾器的演示代碼

一、多個裝飾器裝飾同一個函數

import time
def wrapper(func):
    def count_time(*args,**kwargs):
        print("計算時間的裝飾器")
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print("函數運行的時間為:{:.5f}".format(end_time-start_time))
    return count_time

with open("zy/user.txt") as f:
    users=eval(f.read())

def login_check(func):
    def ado(*args,**kwargs):
        print("登錄校驗的裝飾器")
        if not users["token"]:
            print("-----登錄頁面-------")
            username=input("賬號:")
            password=input("密碼:")
            if users["user"] == username and users["pwd"] == password:
                users["token"] =True
                func(*args,**kwargs)
        else:
            func()
    return ado

@login_check # 第二步進行裝飾  count_time---->func=login_check(func)    func指向的是ado這個函數
@wrapper  #  第一步進行裝飾  func=wrapper(func)  func指向的是count_time這個函數。
def func():
    time.sleep(3)
    print("這是是需要被裝飾器的函數")

#  從下往上裝飾,從上往下執行
func()

裝飾的時候是從下往上裝飾,從上往下執行。 運行的時候是:1.先運行@login_check,2.運行@wrapper,3.再運行time.sleep(3)

二、Python 中類裏面三個內置的裝飾器

這個三個內置的裝飾器是在類裏面用的。

1.@classmethod

classmethod裝飾了之後,該方法就是一個類方法。

self出現了下劃波浪線,說明它不符合 pep8 規範。

裝飾和未被裝飾對比圖

被裝飾之後它是一個類方法,那麼這個時候self不會代表實例本身,不是實例對象了。那麼這個參數改成cls

類方法的第一個參數是cls,代表的是類本身。self 代表的是實例本身。

用類不能調用實例的方法:

被 classmethod 裝飾了之後,類就能直接調用了:

classmethod 裝飾之前:實例方法、實例屬性,類都是調用不了的。

2.@staticmethod

靜態方法,默認不需要傳參數(不會傳類也不會傳實例對象),實例和類都可以調用。

3.@property

這個一般用來做設置只讀屬性的。

通過__init__設置的屬性,在外面可以讀也可以改。

比如給實例設置個屬性,這個屬性只能讀,不能改。那這個屬性就設置在@property裏面。

這個是不能改的,改了以後運行會報錯:

要設置可讀屬性的話,通過這種方式,實際上設置的是個方法,方法內部返回的是個值。

這個值,就可以把它看成一個只讀屬性。這個只能讀不能改,哈哈哈。

三、3個內置裝飾器的演示代碼

class MyTest(object):

    def __init__(self,name):#設置一個初始化屬性叫做name
        self.name = name

    @classmethod  # 被classmethod裝飾了之後,該方法就是一個類方法
    def add(cls):# cls  代表的是類本身
        print("add")
        print(cls)

    @staticmethod  # 靜態方法   實例和類都可以調用
    def static():
        print("這個是靜態方法")

    @property  # 設定只讀屬性
    def read_attr(self):
        print("這個裝飾器裝飾完了之後,該方法可以像屬性一樣被調用")
        return  "20歲"

    def sub(self):# self 代表的是實例本身
        print("sub中的self",self)

# MyTest.static() #類調用

t= MyTest("qinghan")
# 通過name可以訪問到這個屬性,可以對這個屬性進行更改
t.name="lily"
# print(t.name)
# t.read_attr="19歲"
print(t.read_attr)
# t.static()#實例調用
# t.add()
# t.sub()

公眾號清菡軟件測試首發,更多原創文章:清菡軟件測試 117+原創文章,歡迎關注、交流,禁止第三方擅自轉載。