Heim > Backend-Entwicklung > Python-Tutorial > Ein genauerer Blick auf die Python-Dekoratorfunktionen

Ein genauerer Blick auf die Python-Dekoratorfunktionen

WBOY
Freigeben: 2022-06-24 12:51:56
nach vorne
2033 Leute haben es durchsucht

Dieser Artikel vermittelt Ihnen relevantes Wissen über Python. Er organisiert hauptsächlich Probleme im Zusammenhang mit Dekoratorfunktionen, einschließlich des Bildungsprozesses, des Wesens und der Funktion, der Weiterentwicklung und Optimierung von Dekoratoren usw. Das Folgende ist: Werfen wir einen Blick darauf und hoffen, dass es allen hilft .

Ein genauerer Blick auf die Python-Dekoratorfunktionen

Empfohlenes Lernen: Python

Wenn ich eine Funktion für

def f():
    print('hello')
Nach dem Login kopieren

schreibe und dann wissen möchte, wie lange es dauert, diese Funktion auszuführen, ist das einfach, ich muss nur den Code ändern Folgendes

rrree

Aber dann habe ich unzählige Funktionen f2, f3...fn geschrieben. Ich wollte wissen, wie viel Zeit die Ausführung jeder Funktion benötigt. Wäre es nicht sehr ärgerlich, wenn ich sie alle wie oben beschrieben ändern würde? Immer noch nicht möglich, da es zu aufwändig wäre. Was zu tun? Also hatte ich eine Idee und schrieb eine Timer-Funktion. . .

import time
def f():
    start = time.time()   #获取程序执行开始的时间
    print('hello')
    end = time.time()     #获取程序执行结束的时间
    print(end - start)    #得出函数f执行所要时间

f()
Nach dem Login kopieren

Sieht das nicht viel einfacher aus? Egal wie viele Funktionen wir schreiben, wir können diese Timing-Funktion aufrufen, um die Ausführungszeit der Funktion zu berechnen

Aber wenn ich diese Funktion nur auf die ursprüngliche Weise aufrufen möchte f1(), f2(), fn(), das Die Funktion wird auf die ursprüngliche Weise ausgeführt. Unter der Voraussetzung, dass das Ausgabeergebnis unverändert bleibt, kann die Funktion zur Berechnung der Zeit hinzugefügt werden. Anstelle des Aufrufs von timer(f) kann timer(f2) die Zeit berechnen.

Sie werden wissen, wie Sie dieses Problem lösen können, nachdem Sie die folgende Dekoratorfunktion gelesen haben Ich sagte, ich möchte diese Funktion nur auf die ursprüngliche Art und Weise aufrufen: f1(), f2(), fn(). Die Funktion kann auch die Berechnungszeit verlängern, ohne das ursprüngliche Ausführungsergebnis zu ändern, aber ich muss sie trotzdem in Funktion f ausführen Finden Sie es ärgerlich, f = timer(f) in diese Codezeichenfolge zu schreiben? Auch Python-Entwickler finden es nervig, deshalb stellen uns Python-Entwickler einen „syntaktischen Zucker“ zur Verfügung, um dieses Problem zu lösen!



2. Decorator – Erste Einführung in syntaktischen Zucker

Ersetzen Sie f = timer(f) durch @timmer. Dies ist ein Satz aus syntaktischem Zucker.

import time
def timer(func):
    start = time.time()
    func()
    print(time.time() - start)

def f():
    print('hello')


def f2():
    print('xorld')

timer(f)
timer(f2)
Nach dem Login kopieren

3. Dekorator – Essenz und Funktion


1. Essenz

Die Essenz des Dekorators ist eine Abschlussfunktion


2. Funktion

Ohne Änderung der ursprünglichen Funktion und ihrer Aufrufmethode Erweitern Sie die Funktion der ursprünglichen Funktion unter bestimmten Umständen

4. Dekoratoren – Dekoratoren mit Parametern und Rückgabewerten

1. Funktionen mit einem Parameter dekorieren

Die Dekoratoren, die wir gerade geschrieben haben, dekorieren alle eine Funktion ohne Parameter. Was soll ich jetzt tun, wenn ich eine Funktion mit Parametern dekorieren möchte?

import time

def f():
    print('hello')

def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

f = timer(f)
f()
Nach dem Login kopieren

    2. Dekorieren Sie mehrere Funktionen mit unterschiedlichen Parametern, aber ohne Rückgabewert
  • Tatsächlich ist es nicht schwierig, Funktionen mit Parametern zu dekorieren, aber wenn Sie zwei Funktionen haben, sind die Parameter, die übergeben werden müssen, unterschiedlich ,Zum Beispiel hat die Funktion func1 zwei Parameter func1(a,b), die Funktion func2 hat nur einen Parameter func2(a) und beide möchten mit diesem Dekorator dekoriert werden, um die Ausführungszeit der Funktion zu berechnen? Was zu tun? Dann verwenden Sie den folgenden Code.
import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> 写着这句话就相当于执行了f = timer(f)
def f():
    print('hello')


f()
Nach dem Login kopieren

    3. Dekorieren Sie mehrere Funktionen mit unterschiedlichen Parametern und Rückgabewerten
  • Jetzt ist das Parameterproblem perfekt gelöst, aber was ist, wenn Ihre Funktion einen Rückgabewert hat? Mit dem obigen Code können Sie den Rückgabewert nicht ermitteln. Wie lässt sich dieses Problem lösen? Dann schauen Sie sich den Code unten an!
import time
def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def f(a):
    print(a)

f('hello')
Nach dem Login kopieren

    4. Mehrere Dekorateure dekorieren dieselbe Funktion
  • Manchmal verwenden wir auch mehrere Dekorateure, um dieselbe Funktion zu dekorieren.
import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print('in func1')

@timer   #==> func2 = timer(func2)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))

输出结果:
in func1
0.0
in func2 and get a:aaaaaa
0.0
fun2 over
Nach dem Login kopieren

    5. Decorator-Entwicklung und -Optimierung
  • 1. Der Decorator mit Parametern ist bereits sehr schön, aber es gibt immer noch ein Problem, wenn ich unzählige Funktionen im Code habe der syntaktische Zucker von @timer hinzugefügt. Wenn ich es nicht mehr verwenden möchte, müsste ich es dann nicht erneut auskommentieren und 3 Tage lang Tag und Nacht arbeiten? Ist das nicht besonders problematisch? Um die Dekoratoren besser zu recyceln, wenn sie nicht verwendet werden, anstatt sie einzeln zu kommentieren oder zu löschen, führen wir das Konzept der Dekoratoren mit Parametern ein
'''
为了使装饰器不用时能够更好的回收而不是一个一个去注释或者删除
我们引入带参数的装饰器概念
'''

import time
'''FLAGE的目的是用它控制装饰器的开关,
那么当我们不用的时候就不要一个一个去注释只需将True改为False就行'''

FLAGE = True
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end - start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer
@timmer_out(FLAGE)

#timmer_out(FLAGE)
# 也相当于执行  timmer_out(FLAGE)--->>返回timmer———————>>@timmer(wahaha = timmer(wahaha))
def wahaha():
    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间
    print('wahahahahahaha')

wahaha()

@timmer_out(FLAGE)
def erguotou():
    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间
    print('erguotoutoutou')

erguotou()

输出结果:
wahahahahahaha
0.10152268409729004
erguotoutoutou
0.10795140266418457
Nach dem Login kopieren
  • 2、防止函数必要信息失效

'''
print(wahaha.__name__)      #查看字符串格式的函数名
print(wahaha.__doc__)       #查看一个函数的注释
'''
#下面用__name__查看holiday的函数名

from functools import wraps
def wrapper(func):
    @wraps(func)            #加在最内层函数正上方
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前做的事')
        ret = func(*args,**kwargs)
        print('在被装饰的函数执行之后做的事')
        return ret
    return inner

@wrapper        #holiday = wrapper(holiday)
def holiday(day):
    '''
    这是一个放假通知
    :param day:
    :return:
    '''
    print('全体放假%s天'%day)
    return '好开心'

print(holiday.__name__)
print(holiday.__doc__)
'''
结果是inner和None 但我们想要的是打印holiday的字符串格式的函数名和函数的注释这时该怎么办?
解决方法就是  from functools import wraps
使用语法是@wraps(被装饰的函数名)
'''

输出结果:
holiday

    这是一个放假通知
    :param day:
    :return:
Nach dem Login kopieren


六、装饰器 —— 装饰原则

  • 1、开放封闭原则

1.对原函数的功能扩展是开放的

        为什么要对功能扩展开放呢?

    对于任何一个程序来说,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许后来扩展、添加新功能。

2.对修改是封闭的

        为什么要对修改封闭呢?

                就像我们刚刚提到的,因为我们写的一个函数,很有可能在其他地方已经被导入使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经正在使用该函数的代码。

装饰器就完美遵循了这个开放封闭原则。这就是学装饰器的初衷



小结:

  • 1、装饰器的固定格式(模板)

#格式一

def timer(func):
    def inner(*args,**kwargs):
        '''执行函数之前要做的'''
        re = func(*args,**kwargs)
        '''执行函数之后要做的'''
        return re
    return inner

#格式二

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper
Nach dem Login kopieren

推荐学习:python

Das obige ist der detaillierte Inhalt vonEin genauerer Blick auf die Python-Dekoratorfunktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage