python 装饰器执行顺序
阿神
阿神 2017-04-17 17:38:40
0
2
330
#!/usr/bin/python**加粗文字**
def deco_functionNeedDoc(func):
        if func.__doc__ == None:
                print func,"has no __doc__, it's a bad habit."
        else:
                print func,':',func.__doc__,'.'
        return func

@deco_functionNeedDoc
def f():
        print 'f() Do something'

@deco_functionNeedDoc
def g():
        'I have a __doc__'
        print 'g() Do something'
f()
g()

Actual Result:
<function f at 0x7f31e65d05f0> has no __doc__, it's a bad habit.
<function g at 0x7f31e65d0668> : I have a doc .
f() Do something
g() Do something

Expected Result:
<function f at 0x7f31e65d05f0> has no __doc__, it's a bad habit.
f() Do something
<function g at 0x7f31e65d0668> : I have a doc .
g() Do something
f()和g()被修饰后是如何执行的?

另外一段使用装饰器的代码

#-*- coding: UTF-8 -*-  
import time

def timeit(func):
    def wrapper():
        start = time.clock()
        func()
        end =time.clock()
        print 'used:', end - start
    return wrapper

@timeit
def foo():
    print 'in foo()'

foo()

Actual Result:

in foo()
used: 2.1e-05

这一段使用wrapper方法执行时先执行foo(),再执行wrapper()。
加了wrapper会有什么差别吗?

阿神
阿神

闭关修行中......

répondre à tous(2)
洪涛

Le décorateur ressemble plus à un programme exécuté "au moment de la compilation". Il "décore" la fonction avant même que la fonction d'origine ne soit chargée en mémoire, voici donc le programme décoré qui est d'abord décoré puis exécuté. Sinon, vous pouvez essayer d'exécuter le code dans la fonction décorée sans exécuter f() ou g() à la fin

洪涛

Python est un environnement d'exécution semi-compilé et semi-interprété. Le code source est d'abord compilé en bytecode, puis ces bytecodes sont exécutés pour obtenir les résultats.

La fonction est rebondie après passage au décorateur, c'est à dire

f = deco_functionNeedDoc(f)

Le décorateur doit donc faire partie de l'objet fonction. En d'autres termes, cette étape consiste à ce que le code soit "codé en dur" lors de la compilation, c'est-à-dire lorsqu'il est compilé en bytecode. Ceci est similaire aux paramètres par défaut. de la fonction

def func(a = []):
    pass

Ils sont tous déterminés lors de la phase de compilation. Ainsi, votre code est définitivement expliqué. Dans la phase de compilation, le décorateur est d'abord exécuté pour relier la fonction, puis dans la phase d'exécution, les éléments de f sont directement exécutés.
PS : Votre exemple de décorateur n'est pas typique. Vous pouvez en trouver qui enveloppent la fonction d'origine
Ce qui précède est ma compréhension personnelle, discutons-en ensemble


La fonction de décorateur wrap modifiée est en fait la fonction timeit qui est exécutée en premier, mais elle ne produit rien, mais renvoie directement un objet fonction. Par exemple, si vous ajoutez :


#-*- coding: UTF-8 -*-  
import time

def timeit(func):
    def wrapper():
        start = time.clock()
        func()
        end =time.clock()
        print 'used:', end - start
    print 'I am timeit'
    return wrapper

@timeit
def foo():
    print 'in foo()'

foo()

La sortie va changer, sortie I am timeit d'abord. Regardez ce que j'ai dit ci-dessus, le décorateur relie la fonction et renvoie une autre fonction. Elle est terminée lors de la compilation, et lors de sa nouvelle exécution, la nouvelle fonction sera exécutée directement. C'est votre wrapper

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal