根据变量名声明函数名的更好方法?

问题描述 投票:0回答:1

假设我有一个如下的函数,我想根据变量名有多个函数。

@app.route('/foo', methods=['GET', 'POST'])
def foo():
   print("food")
   return "OK"

我想根据变量名声明多个函数,我是这样实现的。

from flask import Flask

app = Flask(__name__)
methods = ['GET', 'POST']
names = ['foo', 'fubu', 'fomo', 'bar']
for name in names:
    exec(f"""
@app.route('/{name}', methods=methods)
def {name}():
    print('NAMED {name}')
    return '{name} - Example'
    """)

我读到这样的使用方法 exec()极不情愿 要用,如果用了就意味着我做错了。

请问有什么最好的方法来实现,因为这种方法是不好的。

我想实现的是让我的应用接受存储在内存中的额外的JSON配置文件,并包含所有这些指令,如果主管理员在编辑时输入正确的第二长密码,则加载它们。

PS:这个应用不会得到任何用户的输入,只能由超级管理员修改。

python flask dynamic routes dynamic-programming
1个回答
0
投票

从问题的评论来看。

@LoïcFaure-Lacroix 我想让管理员能够添加新的路由,而不需要硬编码,我的意思是管理员可以选择加载哪些模块,路由名称,数据库模型,也可以添加代码,在该路由中执行... ... 必须提供第二个密码才能修改配置文件

我不会让你这么做。任何有正确凭证的人都能直接在服务器上执行代码,并给运行应用程序的用户提供几乎所有的凭证来执行任何事情。

你可以使用 编制exec 来快速生成代码。思想,我相信你想实现这个目标的原因是错误的。

如果你想在运行时扩展你的应用程序,你最好在你的应用程序中加入一个插件api。

就像这样。

class MyPlugin(Plugin):
    def info(self):
        # return information about the module/plugin

    def register(self, application):
        # register the plugin into the application

    def unregister(self):
        # do cleanup

所以你的每一个插件都可以被定义为可以安装的python包。每一个python包都会暴露出一个入口点,甚至是命名空间模块。

https:/packaging.python.orgguidescreating-and-discovering-plugins。

当你得到你的 entrypointmodule,你调用插件类或简单的方法来注册它。

你的主程序要做的就是在运行时发现已安装的插件并加载卸载它们。

你直接在服务器上执行代码的问题是它不可维护。你没有任何设施来卸载你所做的改变,事情迟早会崩溃。让python代码编译是一个巨大的安全风险,如果你能通过手动安装一套可以在运行时被发现的包来摆脱,这样更安全,更容易管理。

凡是涉及到添加更多的路由,可以用你所使用的库的API来完成,凡是涉及到添加配置文件数据库等。都可以直接通过存储配置来完成。在99%的情况下,几乎没有理由直接从python代码内编译python代码。


1
投票

名字可能并不重要。比如,你可以这样做。

def function_maker(name):
    def _():
        print(f'Named {name}')
        return '{name} - Example'
    _.__name__ = name
    return _

然后

for name in ['foo', 'fubu', 'fomo', 'bar']:
    @app.route(f'/{name}', methods=methods)(function_maker(name))

的定义可能会有细微的差别。def foo():...def _():...但这些都不可能是重要的。

© www.soinside.com 2019 - 2024. All rights reserved.