Heim > Backend-Entwicklung > Python-Tutorial > Python-Dekorator – eine Methode zur Begrenzung der Anzahl von Funktionsaufrufen (Aufruf einmal alle 10 Sekunden)

Python-Dekorator – eine Methode zur Begrenzung der Anzahl von Funktionsaufrufen (Aufruf einmal alle 10 Sekunden)

不言
Freigeben: 2018-04-21 14:34:59
Original
2455 Leute haben es durchsucht

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)
Nach dem Login kopieren

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
Nach dem Login kopieren

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'
Nach dem Login kopieren

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'
Nach dem Login kopieren

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
Nach dem Login kopieren

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 &#39;call func&#39;
Nach dem Login kopieren

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
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage