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 .
Empfohlenes Lernen: Python
Wenn ich eine Funktion für
def f(): print('hello')
schreibe und dann wissen möchte, wie lange es dauert, diese Funktion auszuführen, ist das einfach, ich muss nur den Code ändern Folgendes
rrreeAber 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()
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!
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)
3. Dekorator – Essenz und Funktion
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()
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()
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')
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
''' 为了使装饰器不用时能够更好的回收而不是一个一个去注释或者删除 我们引入带参数的装饰器概念 ''' 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
''' 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:
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
推荐学习: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!