【问题标题】:Applying a decorator to an imported function?将装饰器应用于导入的函数?
【发布时间】:2014-11-07 21:02:44
【问题描述】:

我要导入一个函数:

from random import randint

然后对其应用装饰器:

@decorator
randint

我想知道这是否有一些语法糖(就像我上面所说的那样),还是我必须按如下方式进行:

@decorator
def randintWrapper(*args):
    return random.randint(*args)

【问题讨论】:

标签: python function decorator python-decorators


【解决方案1】:

装饰器只是用装饰版本替换函数对象的语法糖,其中装饰只是调用(传入原始函数对象)。换句话说,语法:

@decorator_expression
def function_name():
    # function body

大致(*)翻译成:

def function_name():
    # function body
function_name = decorator_expression(function_name)

在你的情况下,你可以手动应用你的装饰器:

from random import randint

randint = decorator(randint)

(*) 在函数或类上使用@<decorator> 时,defclass 定义的结果首先不会绑定(分配给它们在当前命名空间中的名称) .装饰器直接从栈中传递对象,然后只绑定装饰器调用的结果。

【讨论】:

  • 唯一的问题是没有保留文档字符串和方法名称。也许想用functools.wraps
  • @pratikm:不过这是一个单独的问题。装饰器确实应该使用functools.wraps,但这不会改变你如何应用装饰器。
  • 这似乎不适用于烧瓶路由装饰器。那是@app.route('/route', methods=['GET'])
  • @CMCDragonkai:它适用于 Flask 路由装饰器,只要您调用装饰器工厂的结果:app.route('/route', methods=['GET'])(view_func)(无需捕获返回值,因为 app.route() 装饰器注册,并返回未更改的视图函数)。并不是说您应该这样做,因为您可以使用 app.add_url_rule() 代替:app.add_url_rule('/route', view_func.__name__, view_func, methods=['GET'])
  • @CoreyLevinson 这些术语是装饰器工厂。就像 Flask route 装饰器工厂一样,它是返回实际装饰器的调用。这通常用于配置正在生成的装饰器。例如。 autocast() 采用 enabled 参数。
猜你喜欢
  • 2015-02-01
  • 2011-06-24
  • 2017-01-25
  • 2015-08-14
  • 2018-06-25
  • 2012-07-05
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多