【问题标题】:Can I run a decorated function without a decorator functionality?我可以在没有装饰器功能的情况下运行装饰功能吗?
【发布时间】:2020-12-10 05:02:52
【问题描述】:

如果我曾经在我的函数中使用了装饰器,我怎么能单独运行这个函数,而不嵌入到装饰器功能中?

例如,我有一个函数printArg,它会打印一个参数。对于某些可用性,我需要将它与datetime.now()“混合”。为此我写了一个装饰器timeCalled。现在每次我打电话给printArg 时也会调用一个装饰器。

有没有办法单独调用printArg,所以我不会重复自己并写另一个没有装饰器功能的“printArg”(datetime.now())?

from datetime import datetime

def timeCalled(func):
    def wrapper(*args, **kwargs):
        print(f'{datetime.now()}: Function called {func.__name__}')
        result = func(*args, **kwargs)
        return result
    return wrapper

@timeCalled
def printArg(arg):
    print(f'Your arg is {arg}')

printArg('Mama')

【问题讨论】:

标签: python python-3.x decorator python-decorators


【解决方案1】:

没有不依赖于实现细节的通用方法。在这种特殊情况中,由于func 引用了wrapper 中的原始函数并且在闭包中,您可以使用:

printArg.__closure__[0].cell_contents

检索它。

更一般地说,在创建包装器时使用functools.wraps 是一种很好的做法,这会使包装器函数“看起来像”原始函数。此外,它将原始函数添加到 __wrapped__ 属性中,因此:

from datetime import datetime
from functools import wraps

def timeCalled(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f'{datetime.now()}: Function called {func.__name__}')
        result = func(*args, **kwargs)
        return result
    return wrapper

@timeCalled
def printArg(arg):
    print(f'Your arg is {name}')

在这种情况下,您可以使用:

printArg.__wrapped__

【讨论】:

  • 短时间内回答这么多!我正在按照你的答案写一些东西,所以你有我的支持!
【解决方案2】:

装饰器只是被装饰函数的包装函数,语法如下:

@timeCalled
def printArg(arg):
    pass

相当于:

def printArg(arg):
    pass
printArg = timeCalled(printArg)

所以为了达到避免定义相同的函数两次,只有一个被装饰的目标,你可以定义一次函数,然后调用装饰器并将所述函数传递给它,并将返回的函数对象分配给不同的名称而是:

def printArg(arg):
    print(f'Your arg is {name}')

timed_printArg = timeCalled(printArg)

这样您就可以调用timed_printArg('Mama')printArg('Mama') 进行定时调用,并直接调用printArg('Mama') 来执行此操作,而不涉及装饰器。

【讨论】:

    【解决方案3】:

    给你的装饰函数一个不同的名字。为此,请勿使用@ 表示法,而是:

    decorated_printArg = timeCalled(printArg)
    

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 2022-01-09
      • 2016-02-14
      • 1970-01-01
      • 2017-11-19
      • 2021-12-05
      • 2023-03-28
      • 1970-01-01
      • 2015-07-07
      相关资源
      最近更新 更多