python – Verwenden von __call__ zum Implementieren von Dekoratorfunktionen
某草草
某草草 2017-06-28 09:24:02
0
1
864

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?

某草草
某草草

Antworte allen(1)
迷茫

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

不带参数的类式装饰器

如果创建了一个不带参数的装饰器,被装饰的方法会传递给装饰器的构造器(__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...

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage