suchen

Heim  >  Fragen und Antworten  >  Hauptteil

python – Verwenden von __call__ zum Implementieren von Dekoratorfunktionen

Verwenden Sie den __call__ einer Klasse, um einen Dekorator zu implementieren, wie im folgenden Code gezeigt



class Check(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, func):

        print "1111111111"

        def _decorator(*args, **kwargs):
            print "2222222222"
            return func(*args, **kwargs)
          

Wenn Sie diese Klasse als Dekorateur verwenden, um eine Veranstaltung zu dekorieren.

@Check("param")
def param_check(request):
    "python code....."
    return Response("ok")

Hier kommt das Problem. Starten Sie einen Django- oder einen anderen Python-Prozess. Beim Ausführen dieser param_check-Route wird print „1111111111“ nur zum ersten Mal gedruckt und 1111111111111 wird bei einem späteren Aufruf nicht gedruckt.
Und der Aufdruck „2222222222“ wird jedes Mal gedruckt. Meines Wissens nach definiert __call__ diesen Dekorator zum ersten Mal und wird daher nur einmal ausgeführt. Er wurde definiert, wenn er später erneut angefordert wurde, und nur der Funktionskörperteil wird ausgeführt, nämlich der Teil print 222222222. Wer kennt die Funktionen dieses Python-Dekorators?

某草草某草草2764 Tage vor881

Antworte allen(1)Ich werde antworten

  • 迷茫

    迷茫2017-06-28 09:26:02

    其实用类式装饰器时,有个需要注意的地方,有参数和无参数的类式装饰器其实是不一样的

    不带参数的类式装饰器

    如果创建了一个不带参数的装饰器,被装饰的方法会传递给装饰器的构造器(__init__),然后在被装饰的函数被调用的时候,装饰器的__call__()方法就会执行。

    class Check(object):
    
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args):
    
            print("111111")
            self.func(*args)
            print("222222")
    
    @Check
    def param_check(request):
        print(request)
    
    
    
    param_check('hello')
    param_check('world')
    
    111111
    hello
    222222
    111111
    world
    222222

    需要注意,在装饰阶段,__init__ 函数执行,在被装饰的方法被调用的时候,__call__ 执行。

    带参数的类式装饰器

    class Check(object):
        def __init__(self, name):
            self.name = name
    
        def __call__(self, func):
    
            print ("1111111111")
    
            def decorator(*args, **kwargs):
                print ("2222222222")
                return func(*args, **kwargs)
            return decorator
    
    @Check('parm')
    def param_check():
        print('Hello')
    
    param_check()
    param_check()

    输出:

    1111111111
    2222222222
    Hello
    2222222222
    Hello

    可以很明显的看出来, __call__只会在装饰阶段被调用一次

    想了解的更详细看这儿: http://www.artima.com/weblogs...

    Antwort
    0
  • StornierenAntwort