91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中裝飾器代碼是怎么樣的

發布時間:2021-10-27 15:28:05 來源:億速云 閱讀:193 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“Python中裝飾器代碼是怎么樣的”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Python中裝飾器代碼是怎么樣的”這篇文章吧。

    一、理解裝飾器

    所有東西都是對象(函數可以當做對象傳遞)
    由于函數也是一個對象,而且函數對象可以被賦值給變量,所以,通過變量也能調用該函數。

    def function_one():
        print("測試函數")
    #可以將一個函數賦值給一個變量,比如
    foo =function_one #這里沒有在使用小括號,因為我們并不是在調用function_one函數,而是在將它放在foo變量里。
    foo()
    '''
    測試函數
    Process finished with exit code 0
    '''

    閉包的概念:

    1)函數嵌套

    2)內部函數使用外部函數的變量

    3)外部函數的返回值為內部函數

    示例:

    def outer_function(message):
        def inner_function():
            print(message)
        return inner_function
    func = outer_function("你好")
    func() #你好

    二、裝飾器原型

    裝飾器的作用就是 不修改源代碼以及原函數調用方式的情況下 給原函數增加新的功能。

    #將函數作為參數傳給另一個函數
    def decorator_function(original_function):
        def wrapper_function():
        	print('wrapper executed this before {}'.format(original_function.__name__))
            original_function()
        return wrapper_function
        '''
        返回wrapper_function而不是wrapper_function();這是因為當你把一對小括號放在后面,這個函數就會執行;
        然而如果你不放括號在它后面,那它可以被到處傳遞,并且可以賦值給別的變量而不去執行它。
    	'''
    def display():
        print('display function ran')
    decorator_display = decorator_function(display)
    decorator_display()

    運行結果:

    wrapper executed this before display
    display function ran
    Process finished with exit code 0

    1、不帶參數的裝飾器

    def decorator_function(original_function):
        def wrapper_function():
            print('wrapper executed this before {}'.format(original_function.__name__))
            original_function()
        return wrapper_function
    @decorator_function
    def display():  #等價于display =decorator_function(display)
        print('display function ran')
    display()

    運行結果:

    wrapper executed this before display
    display function ran

    Process finished with exit code 0

    2.帶參數的被裝飾的函數

    def decorator_function(original_function):
        def wrapper_function(*args,**kwargs):
            print('wrapper executed this before {}'.format(original_function.__name__))
            original_function(*args,**kwargs)
        return wrapper_function
    @decorator_function
    def display():
        print('display function ran')
    @decorator_function
    def display_info(name,age):
        print('display_info ran with arguments ({},{})'.format(name,age))
    display()
    print('='*50)
    display_info('Michal',20)

    運行結果:

    wrapper executed this before display
    display function ran
    ==================================================
    wrapper executed this before display_info
    display_info ran with arguments (Michal,20)

    Process finished with exit code 0

    運行如下代碼會出現一個問題

    def decorator_function(original_function):
        def wrapper_function(*args,**kwargs):
            print('wrapper executed this before {}'.format(original_function.__name__))
            original_function(*args,**kwargs)
        return wrapper_function
    @decorator_function
    def display():
        print('display function ran')
    @decorator_function
    def display_info(name,age):
        print('display_info ran with arguments ({},{})'.format(name,age))
    display_info = decorator_function(display_info)
    print(display_info.__name__)

    wrapper_function

    Process finished with exit code 0

    輸出的應該是display_info,這里的函數被wrapper_function替代了,重寫了我們函數的名字和注釋文檔(docstring)。Python中可以使用functools.wraps來解決這個問題。

    from functools import wraps
    def decorator_function(original_function):
        @wraps(original_function)
        def wrapper_function(*args,**kwargs):
            print('wrapper executed this before {}'.format(original_function.__name__))
            original_function(*args,**kwargs)
        return wrapper_function
    @decorator_function
    def display():
        print('display function ran')
    @decorator_function
    def display_info(name,age):
        print('display_info ran with arguments ({},{})'.format(name,age))
    display_info = decorator_function(display_info)
    print(display_info.__name__)

    運行結果:

    display_info

    Process finished with exit code 0

    3.帶參數的裝飾器

    在函數中嵌入裝飾器

    from functools import wraps
    def logit(logfile='out.log'):
        def logging_decorator(func):
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打開logfile,并寫入內容
                with open(logfile, 'a') as opened_file:
                    # 現在將日志打到指定的logfile
                    opened_file.write(log_string + '\n')
                return func(*args, **kwargs)
            return wrapped_function
        return logging_decorator
    @logit()
    def myfunc1():
        pass
    myfunc1()
    # Output: myfunc1 was called
    # 現在一個叫做 out.log 的文件出現了,里面的內容就是上面的字符串
    @logit(logfile='func2.log')
    def myfunc2():
        pass
    myfunc2()
    # Output: myfunc2 was called
    # 現在一個叫做 func2.log 的文件出現了,里面的內容就是上面的字符串

    4.使用類作為裝飾器

    class myDecorator(object):
         def __init__(self, f):
             print("inside myDecorator.__init__()")
             f() # Prove that function definition has completed
         def __call__(self):
             print("inside myDecorator.__call__()")
     
     @myDecorator
     def aFunction():
         print("inside aFunction()")
     
     print("Finished decorating aFunction()")
     
     aFunction()

    運行結果:

    inside myDecorator.__init__()
    inside aFunction()
    Finished decorating aFunction()
    inside myDecorator.__call__()
    Process finished with exit code 0

    被裝飾后的函數aFunction()實際上已經是類myDecorator的對象。當再調用aFunction()函數時,實際上就是調用類myDecorator的對象,因此會調用到類myDecorator的__call__()方法。

    因此使用類作為裝飾器裝飾函數來對函數添加一些額外的屬性或功能時,一般會在類的__init__()方法中記錄傳入的函數,再在__call__()調用修飾的函數及其它額外處理。

    class entryExit(object):
         def __init__(self, f):
             self.f = f
         def __call__(self):
             print("Entering", self.f.__name__)
             self.f()
             print("Exited", self.f.__name__)
     
     @entryExit
     def func1():
         print("inside func1()")
     
     @entryExit
     def func2():
         print("inside func2()")
     
     func1()
     func2()

    運行結果:

    Entering func1
    inside func1()
    Exited func1
    Entering func2
    inside func2()
    Exited func2

    Process finished with exit code 0

    5.使用對象作為裝飾器

    空參:

    from functools import wraps
    class decorator_class:
        def __init__(self):
            print('執行decorator_class類的__init__()方法')
        def __call__(self, original_function):
            print('執行decorator_class類的__call__()方法')
            @wraps(original_function)
            def wrapped_function(*args, **kwargs):
                print('call method executed this before {}'.format(original_function.__name__))
                print('執行' + original_function.__name__ + '()')
                original_function(*args, **kwargs)
                print(original_function.__name__ + '()執行完畢')
            return wrapped_function
    @decorator_class()
    def display_info(name,age):
        print('display_info ran with arguments ({},{})'.format(name,age))
    display_info('Michael',20)

    運行結果如下:

    執行decorator_class類的__init__()方法
    執行decorator_class類的__call__()方法
    call method executed this before display_info
    執行display_info()
    display_info ran with arguments (Michael,20)
    display_info()執行完畢

    Process finished with exit code 0

    帶參數:

    from functools import wraps
    class decorator_class:
        def __init__(self,arg1, arg2):
            print('執行decorator_class類的__init__()方法')
            self.arg1 =arg1
            self.arg2=arg2
        def __call__(self, original_function):
            print('執行decorator_class類的__call__()方法')
            @wraps(original_function)
            def wrapped_function(*args, **kwargs):
            	print('執行wrapped_function()')
                print('call method executed this before {}'.format(original_function.__name__))
                print('裝飾器參數:', self.arg1, self.arg2)
                print('執行' + original_function.__name__ + '()')
                original_function(*args, **kwargs)
                print(original_function.__name__ + '()執行完畢')
            return wrapped_function
    @decorator_class('Hello', 'World')
    def display_info(name,age):
        print('display_info ran with arguments ({},{})'.format(name,age))
    display_info('Michael',20)

    運行結果如下:

    執行decorator_class類的__init__()方法
    執行decorator_class類的__call__()方法
    執行wrapped_function()
    call method executed this before display_info
    裝飾器參數: Hello World
    執行display_info()
    display_info ran with arguments (Michael,20)
    display_info()執行完畢

    Process finished with exit code 0

    示例2:

    from functools import wraps
    class logit(object):
        def __init__(self, logfile='out.log'):
            self.logfile = logfile
        def __call__(self, func):
            @wraps(func)
            def wrapped_function(*args, **kwargs):
                log_string = func.__name__ + " was called"
                print(log_string)
                # 打開logfile并寫入
                with open(self.logfile, 'a') as opened_file:
                    # 現在將日志打到指定的文件
                    opened_file.write(log_string + '\n')
                # 現在,發送一個通知
                self.notify()
                return func(*args, **kwargs)
            return wrapped_function
        def notify(self):
            # logit只打日志,不做別的
            pass
    @logit()
    def myfunc1():
        pass

    6.多層裝飾器的嵌套

    #裝飾器1
    def decorator1(func):
        #定義裝飾之后的函數
        def wrapper1():
            # 裝飾器1
            print('1-----裝飾1之前')
            # 調用基本函數
            func()
            # 擴展功能2
            print('1-----裝飾1之后')
        return wrapper1
    #裝飾器2
    def decorator2(func):
        #定義裝飾之后的函數
        def wrapper2():
            # 裝飾器2
            print('2-----裝飾2之前')
            # 調用基本函數
            func()
            # 擴展功能2
            print('2-----裝飾2之后')
        return wrapper2
    #基本函數
    @decorator2   # 第二步:test = decorator2(eat) = test2
    @decorator1   # 第一步:test = decorator1(eat)  = test1
    def test():
        print('測試')
    #調用函數
    test()

    運行結果:

    2-----裝飾2之前
    1-----裝飾1之前
    測試
    1-----裝飾1之后
    2-----裝飾2之后

    Process finished with exit code 0

    以上是“Python中裝飾器代碼是怎么樣的”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    秀山| 盐边县| 博野县| 大同县| 扎鲁特旗| 广汉市| 鹰潭市| 富平县| 行唐县| 嘉定区| 安远县| 永安市| 左权县| 荔波县| 郸城县| 曲阳县| 隆回县| 明溪县| 云龙县| 长治县| 正蓝旗| 察隅县| 资阳市| 台中市| 穆棱市| 台安县| 沁阳市| 寿光市| 北碚区| 施甸县| 榕江县| 衢州市| 满城县| 昌平区| 阜城县| 呈贡县| 革吉县| 沙坪坝区| 四川省| 黄浦区| 敦化市|