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

该博客探讨了Python装饰器中关于参数传递的一个特定表达式`return decorator if isinstance(text, str) else decorator(text)`的含义。文章以廖雪峰老师的作业为背景,解释了在没有明确指定`text`时,装饰器如何接收函数名作为参数。通过示例代码展示了如果省略该表达式,装饰器将如何错误地接收函数名和参数,导致不期望的结果。" 115011224,5561017,理解与解析FHIR格式数据,"['智慧医疗', '数据解析', 'FHIR', 'HL7', 'HTTP']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

作业:

# -*- 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,那么就会把函数名传进去,例如运行结果中的‘<function fast at 0x00000243DCBA5EA0>’:

<class 'function'>
<class 'str'>
33
fast is <function fast at 0x00000243DCBA5EA0> 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)

运行结果是:

<class 'function'>
<class 'function'>
text:  <function fast at 0x00000243DCBA5D90>
func:  11
text:  <function slow at 0x00000243DCBC4BF8>
func:  11

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值