繁体   English   中英

Python - 在 Decorator 之后调用预定义的 Function

[英]Python - Call Pre-defined Function after Decorator

我正在构建一个直接的 Flask API。在 API 端点的每个装饰器之后,我必须定义一个 function,它只是调用另一个 function 我在一个单独的文件中。 这工作正常,但似乎是多余的。 我宁愿直接调用预定义的 function,而不必在装饰器之后将其包装在另一个 function 中。 这可能吗?

我目前拥有的:

import routes.Locations as Locations

# POST: /api/v1/locations
@app.route('/locations', methods=['GET'])
def LocationsRead ():
   return Locations.read()

Locations.read() function 看起来像这样:

def read():
   return {
      'id': 1,
      'name': 'READ'
   }

我希望做什么:

import routes.Locations as Locations

# POST: /api/v1/locations
@app.route('/locations', methods=['GET'])
Locations.read()

装饰器的@语法只是语法糖:

def LocationsRead():
   return Locations.read()

LocationsRead = app.route('/locations', methods=['GET'])(LocationsRead)

所以你可以这样做:

LocationsRead = app.route('/locations', methods=['GET'])(Locations.read)

可以说,理解意图需要更长的时间,而且它并不比您的原始代码简洁得多。

除了异常和记录堆栈跟踪之外,您还会丢失一级堆栈跟踪。 这将很难确定在 flask 中将Locations.read添加为路由的位置和方式。堆栈跟踪将从 flask 库直接跳转到routes.Locations:read 如果你想知道路由是如何配置的(例如 URL 是用什么参数化的或者它使用什么方法),那么你必须已经知道“装饰”发生在哪个文件中。 如果你使用普通装饰,你会得到一行指向包含@app.route('/locations', methods=['GET'])的文件。

也就是说,您获得了值得商榷的好处,并有可能使调试变得更加困难。 坚持使用@装饰器语法。

多亏了@Dunes 和@RodrigoRodrigues 的回答,我对它进行了更多研究,发现以下内容适用于有和没有 arguments 传递的端点,例如 ID。 请参阅下面的代码。

# GET: /api/v1/locations
app.route(basepath + '/locations', methods=['GET'])(Locations.read)
# GET: /api/v1/locations/{id}
app.route(basepath + '/locations/<int:id>', methods=['GET'])(Locations.read)
# POST: /api/v1/locations
app.route(basepath + '/locations', methods=['POST'])(Locations.create)
# PUT: /api/v1/locations/{id}
app.route(basepath + '/locations/<int:id>', methods=['PUT'])(Locations.update)
# DELETE: /api/v1/locations/{id}
app.route(basepath + '/locations/<int:id>', methods=['DELETE'])(Locations.delete)

现在,我怀疑这是标准做法,但如果有人希望减少路由声明中的代码量,这是一种方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM