Das Folgende ist ein Python-Dekorator – eine Methode zur Begrenzung der Anzahl von Funktionsaufrufen (Aufruf einmal alle 10 Sekunden). Sie hat einen guten Referenzwert und ich hoffe, dass sie für alle hilfreich ist. Schauen wir uns das gemeinsam an
Dies ist die aktuelle Interviewfrage eines Bloggers aus einem großen Unternehmen. Schreiben Sie einen Dekorateur und beschränken Sie den Aufruf der Funktion alle 10 Sekunden. Damals war es ein schriftlicher Test, und ich habe nur einen groben Code geschrieben. Nach meiner Rückkehr überprüfte ich die Grundkenntnisse der Python-Dekoratoren und beendete das Schreiben des Codes. Beschlossen, einen Blog zu schreiben, um es aufzuzeichnen.
Dekoratoren werden in Dekoratoren mit Parametern und Dekoratoren ohne Parameter unterteilt.
#不带参数的装饰器 @dec1 @dec2 def func(): ... #这个函数声明等价于 func = dec1(dec2(func)) #带参数的装饰器 @dec(some_args) def func(): ... #这个函数声明等价于 func = dec(some_args)(func)
Einige Details, die Sie über Dekoratoren ohne Parameter beachten sollten
1. Über die Dekoratorfunktion (Dekorator) selbst
Daher entspricht ein Dekorator im Allgemeinen zwei Funktionen, eine ist die Dekoratorfunktion, die zum Ausführen einiger Initialisierungsvorgänge verwendet wird, und die andere ist dekoriert_func, die verwendet wird um die Funktion „Zusätzliche Verarbeitung für dekorierte Funktionen“ zu implementieren. Und um einen Verweis auf func aufrechtzuerhalten, wird dekoriert_func im Allgemeinen als interne Funktion des Dekorators verwendet
def decorator(func): def decorator_func() func() return decorated_func
Die Dekoratorfunktion wird nur einmal aufgerufen, wenn die Funktion ist deklariert
Der Dekorator ist eigentlich syntaktischer Zucker. Er wird nach der Deklaration der Funktion aufgerufen, dekoriert_func generiert und die Referenz des func-Symbols durch dekoriert_func ersetzt. Jedes Mal, wenn die Funktion func danach aufgerufen wird, wird dekoriert_func tatsächlich aufgerufen (dies ist sehr wichtig, da nach der Dekoration tatsächlich dekoriert_func jedes Mal aufgerufen wird).
>>> def decorator(func): ... def decorated_func(): ... func(1) ... return decorated_func ... #声明时就被调用 >>> @decorator ... def func(x): ... print x ... decorator being called #使用func()函数实际上使用的是decorated_func函数 >>> func() 1 >>> func.__name__ 'decorated_func'
Wenn Sie sicherstellen möchten, dass der Funktionsname der zurückgegebenen dekorierten_Funktion mit dem Funktionsnamen von func übereinstimmt, sollten Sie dekoriert_func.name hinzufügen = bevor die Decorator-Funktion dekoriert_func zurückgibt. Darüber hinaus stellt das functools-Modul den Wraps-Decorator bereit, um diese Aktion abzuschließen.
#@wraps(func)的操作相当于 #在return decorated_func之前,执行 #decorated_func.__name__ = func.__name__ #func作为装饰器参数传入, #decorated_func则作为wraps返回的函数的参数传入 >>> def decorator(func): ... @wraps(func) ... def decorated_func(): ... func(1) ... return decorated_func ... #声明时就被调用 >>> @decorator ... def func(x): ... print x ... decorator being called #使用func()函数实际上使用的是decorated_func函数 >>> func() 1 >>> func.__name__ 'func'
Die wunderbare Verwendung lokaler Variablen der Decorator-Funktion
Weil der Merkmale des Abschlusses (Einzelheiten finden Sie unter (1) Teilweiser Abschluss). Die vom Dekorator deklarierten Variablen werden von dekoriert_func.func_closure referenziert, sodass nach dem Aufruf der Dekoratormethode die lokalen Variablen der Dekoratormethode nicht recycelt werden. Sie können also die lokalen Variablen der Decorator-Methode als Zähler, Caches usw. verwenden.
Es ist erwähnenswert, dass, wenn Sie den Wert einer Variablen ändern möchten, die Variable ein veränderbares Objekt sein muss, sodass auch ein Zähler mit einer Liste implementiert werden sollte. Und deklarieren Sie, dass die Funktion die Dekoratorfunktion einmal aufruft, damit die Zähler verschiedener Funktionen nicht miteinander in Konflikt geraten, zum Beispiel:
#!/usr/bin/env python #filename decorator.py def decorator(func): #注意这里使用可变对象 a = [0] def decorated_func(*args,**keyargs): func(*args, **keyargs) #因为闭包是浅拷贝,如果是不可变对象,每次调用完成后符号都会被清空,导致错误 a[0] += 1 print "%s have bing called %d times" % (func.__name__, a[0]) return decorated_func @decorator def func(x): print x @decorator def theOtherFunc(x): print x
Fangen wir an, Code zu schreiben:
#coding=UTF-8 #!/usr/bin/env python #filename decorator.py import time from functools import wraps def decorator(func): "cache for function result, which is immutable with fixed arguments" print "initial cache for %s" % func.__name__ cache = {} @wraps(func) def decorated_func(*args,**kwargs): # 函数的名称作为key key = func.__name__ result = None #判断是否存在缓存 if key in cache.keys(): (result, updateTime) = cache[key] #过期时间固定为10秒 if time.time() -updateTime < 10: print "limit call 10s", key result = updateTime else : print "cache expired !!! can call " result = None else: print "no cache for ", key #如果过期,或则没有缓存调用方法 if result is None: result = func(*args, **kwargs) cache[key] = (result, time.time()) return result return decorated_func @decorator def func(x): print 'call func'
Ich habe es gerade getestet und es gibt im Grunde kein Problem.
>>> from decorator import func initial cache for func >>> func(1) no cache for func call func >>> func(1) limit call 10s func 1488082913.239092 >>> func(1) cache expired !!! can call call func >>> func(1) limit call 10s func 1488082923.298204 >>> func(1) cache expired !!! can call call func >>> func(1) limit call 10s func 1488082935.165979 >>> func(1) limit call 10s func 1488082935.165979
Verwandte Empfehlungen:
Python begrenzt die Anzahl der Funktionsaufrufe
Das obige ist der detaillierte Inhalt vonPython-Dekorator – eine Methode zur Begrenzung der Anzahl von Funktionsaufrufen (Aufruf einmal alle 10 Sekunden). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!