合同

2024-10-02 22:35:21 发布

您现在位置:Python中文网/ 问答频道 /正文

协定:以函数为参数并返回函数[即传递函数的修改(或相同)版本]的函数。传递的函数,例如,square。在

@floatify
def square(n):
   return n*n

decorator是否只返回传递函数的装饰版本,而不返回其他函数?在


Tags: 函数版本参数returndef装饰decorator传递函数
3条回答

装饰函数应该返回一个函数,因为它返回的任何内容都将绑定到原始函数的名称。因此,如果返回的对象不是函数(或其他可调用的对象,如类构造函数或可调用类实例),则会令人困惑。在

通常返回的函数应该有一个与原始函数兼容的函数签名,但是我想如果返回的函数也需要额外的参数,那就没问题了。另外,返回函数的返回类型应该与原始函数的返回类型兼容。在

修饰函数有点像原始函数的子类,因此遵循Liskov substitution principle是有意义的。在

装饰功能会有副作用:例如,它可以改变某些全局性。这可能是有用的,例如用于日志记录;因此,函数通常应该避免产生副作用。在

FWIW,一些标准函数修饰符返回非函数可调用项,最常见的可能是@classmethod。在


装潢师没有什么特别神奇的。正如Jared Goguen在评论中提到的

@decorator
def some_function(args):
    #etc

与相同

^{pr2}$

第二种形式稍长一些,但功能更强大,因为如果需要,可以选择将返回的函数绑定到其他名称。使用较长语法可以轻松完成的一些事情,如果不是使用@语法完全不可能做到的话,那么这些事情可能会很困难。在

装饰器可用作

  • 注册装饰师
  • 功能装饰师
  • 参数化装饰器
  • 基于类的装饰器

查询中的代码是函数修饰符,它将修饰函数square)替换为wrapperwrapper执行以下操作:

  • 调用f(n)
  • float应用于result并返回它。在
def floatify(f):
   def wrapper(n):
      result = f(n)
      return float(result)
   return wrapper

功能装饰商合同:

替换函数通常遵循装饰函数的契约:

  • 接受相同数量/种类的参数
  • 返回兼容类型的结果

替换函数应该保存来自修饰函数的元数据

  • 重要的是,为了调试和其他元编程目的,请使用@functools.wraps(f)

它应该只返回一个函数,但是没有什么可以阻止您返回您想要的任何东西。在

>>> def d(x):
...   return "hello"
...
>>> @d
... def f():
...   return "world"
...
>>> f
'hello'
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>>

相关问题 更多 >