装饰器参数传递return decorator if isinstance(text,str) else decorator(text)的解释

起因是廖老师的一个作业:

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000#0

装饰器参数传递return decorator if isinstance(text,str) else decorator(text)的解释_第1张图片

作业:

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 13 19:21:59 2019

@author: chealia
"""
import functools,time
def metric(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args,**kw):
            
            start=time.time()
            f=func(*args,**kw)
            print('%s is %s in %s ms'%(func.__name__,text,time.time()-start))
            return f
        return wrapper
    print(type(text))
    return decorator if isinstance(text,str) else decorator(text)
    
@metric
def fast(x, y):
    time.sleep(0.0012)
    print(x+y)
    return x + y

@metric('execute')
def slow(x, y, z):
    time.sleep(0.1234)
    print(x*y*z)
    return x * y * z

f = fast(11, 22)
s = slow(11, 22, 33)

关于那句 return decorator if isinstance(text,str) else decorator(text)的解释:

装饰器的参数传递是按顺序来的。首先是mertic(text)定义中的text,然后是函数func,然后是函数的参数(*args,**kw),即指(x,y)或者(x,y,z)。如果没有text,那么就会把函数名传进去,例如运行结果中的‘’:



33
fast is  in 0.002995729446411133 ms
7986
slow is execute in 0.13919687271118164 ms

如果把这段return的(text)去掉:

return decorator if isinstance(text,str) else decorator(text)

运行结果就会变成:

TypeError: decorator() takes 1 positional argument but 2 were given

因为传入了两个参数(x,y).

还可以试试这样:

import functools,time
def metric(text):
    def decorator(func):
        print('text: ',text)
        print('func: ',func)
        @functools.wraps(func)
        def wrapper(*args,**kw):
            
            start=time.time()
            f=func(*args,**kw)
            print('%s is %s in %s ms'%(func.__name__,text,time.time()-start))
            return f
        return wrapper
    print(type(text))
    return decorator
    
@metric
def fast(x):
    time.sleep(0.0012)
    print(x*x)
    return x*x

@metric
def slow(x):
    time.sleep(0.1234)
    print(x)
    return x

f = fast(11)
s = slow(11)

运行结果是:



text:  
func:  11
text:  
func:  11

它把函数的名字当成metric(text)的text传进去了,再把函数的参数当做decorator(func)的func传进去了!

你可能感兴趣的:(python)