将装饰器应用于导入的函数?

kyp*_*hos 28 python function decorator python-decorators

我想导入一个函数:

from random import randint
Run Code Online (Sandbox Code Playgroud)

然后应用装饰器:

@decorator
randint
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一些语法糖(就像我上面所说的那样),或者我必须这样做:

@decorator
def randintWrapper(*args):
    return random.randint(*args)
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 39

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

@decorator_expression
def function_name():
    # function body
Run Code Online (Sandbox Code Playgroud)

粗略地(*)转换为:

def function_name():
    # function body
function_name = decorator_expression(function_name)
Run Code Online (Sandbox Code Playgroud)

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

from random import randint

randint = decorator(randint)
Run Code Online (Sandbox Code Playgroud)

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

  • @pratikm:这是一个单独的问题.装饰者确实应该使用`functools.wraps`,但这并没有改变你如何*应用*装饰器. (4认同)
  • @CMCDragonkai:如果你调用装饰器工厂的结果,它对于Flask路径装饰器来说非常好用:`app.route('/ route',methods = ['GET'])(view_func)`(不需要捕获返回值,因为`app.route()`装饰器注册,并返回视图函数未更改).不是你应该这样做,因为你可以只使用[`app.add_url_rule()`](http://flask.pocoo.org/docs/0.12/api/#flask.Flask.add_url_rule):`app .add_url_rule('/ route',view_func .__ name __,view_func,methods = ['GET'])`. (3认同)
  • @CoreyLevinson 这些术语是装饰器*工厂*。与 Flask `route` 装饰器工厂一样,它是返回实际装饰器的调用。这通常用于配置正在生成的装饰器。例如,“autocast()”采用“enabled”参数。 (3认同)
  • 唯一的问题是不保留docstring和方法名称.也许想要使用`functools.wraps` (2认同)