【问题标题】:What functions cannot be decorated in Python?哪些函数不能在 Python 中修饰?
【发布时间】:2020-04-19 11:06:37
【问题描述】:

在大学考试或面试问题设置中,您如何回答:

哪些函数不能在 Python 中修饰?

展示知识的深度是有益的,因此我将首先简要描述 Python 中装饰器的使用。它们的局限性是什么?

我已阅读 Decorator pattern Wiki 并找不到任何反模式。

A.装饰器用途

  1. Python 中的装饰器可用于扩展模块函数、类方法和类本身的功能。例如,对函数或动态编程缓存使用调试日志记录包装器:
@functools.lru_cache(maxsize=128)
def fibonacci(n=10):
    ...
  1. 类也可以充当装饰器(如果您实现了__init__()__call__() 方法)。

  2. 可以包装装饰器以允许传递参数。它也可以与其他装饰器链接。

B.什么时候不能使用装饰器

  1. 您不能将装饰器用于变量赋值、调用函数等。它们仅在定义函数/类/方法时使用。

  2. 您可能不想在递归函数上使用装饰器,因为它有效地将最大递归深度减半(如 @jasonharper 所建议的那样)。

是否还有其他不能(或不应该)使用装饰器的情况?

【问题讨论】:

  • 如果你装饰一个递归函数,你有效地将最大递归深度减半。如果函数出于某种原因想要禁止它,它可能会确定它被修饰(通过使用inspect 模块来查看调用堆栈,很可能)。
  • @jasonharper 说得好!谢谢。
  • 非常感谢重新打开:我添加了一个示例情况,提高了问题的清晰度,并更改了格式。此问题有助于对 Python 中的装饰器的一般理解,展示研究,并满足在 Google 搜索该问题时缺少结果的需求。
  • 很确定你不能装饰一个 lambda 函数。另外,像(x for x in foo) 这样的生成器表达式在技术上定义了一个函数,你也不能装饰它。
  • @kaya3 好建议! is 可以装饰一个 lambda,但你是正确的,因为你不能使用 @decorator 语法。您必须定义 lambda f,然后用 f = decorator(f) 包装它。生成器表达式也很好,谢谢:)

标签: python python-3.x oop decorator


【解决方案1】:

也许我弄错了,但如果你没有使用装饰器的语法糖(“@my_decorator”),那么它是通过将装饰函数分配给你想要装饰的函数来使用的。所以从技术上讲,装饰器可以用于赋值,不仅在函数定义中,还可以将函数赋值给另一个函数:

# let's create a simple decorator
def mydecorator(decorated_func):
    def wrapped(*args, **kwargs):
        print("Something happened in decorator!")
        return decorated_func(*args, **kwargs)
    return wrapped


# let's use decorator with syntactic sugar "@"
@mydecorator
def myfunc(myarg):
    print("my function", myarg)


# just simple function
def mysecond_func(myarg):
    print("my second function", myarg)

# let's decorate the second function with the same decorator,
# but without using syntactic sugar;
# it's identical with the first example with "@"
mysecond_func = mydecorator(mysecond_func)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-07
    • 2014-10-27
    • 2018-01-21
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 2023-03-31
    • 2022-11-02
    相关资源
    最近更新 更多