【问题标题】:import file by url route python通过url路由python导入文件
【发布时间】:2015-01-24 01:08:46
【问题描述】:

我试图在 Flask 应用程序中以 url 路由为基础导入文件。几天前我开始编写 python 代码,所以我不知道我是否做得好。我把这个写在:

@app.route('/<file>')
def call(file):
    __import__('controller.'+file)
    hello = Example('Hello world')
    return hello.msg

我还有一个名为 example.py 的文件到包含以下内容的控制器文件夹中:

class Example:
    def __init__(self, msg):
        self.msg = msg

所以我从终端应用程序开始并尝试输入localhost:5000/example。 我试图在屏幕上显示 Hello world 但给我下一个错误:

NameError: global name 'Example' is not defined

谢谢大家!

【问题讨论】:

  • 您使用__import__(&lt;module&gt;)而不是import module有什么具体原因吗?

标签: python url import flask


【解决方案1】:

__import__ 返回新导入的模块;该模块中的名称​​没有添加到您的全局变量中,因此您需要从返回的模块中获取 Example 类作为属性:

module = __import__('controller.'+file)
hello = module.Example('Hello world')

__import__ 相当低级,您可能想改用importlib.import_module()

import importlib

module = importlib.import_module('controller.'+file)
hello = module.Example('Hello world')

如果您也需要动态获取类名,请使用getattr()

class_name = 'Example'
hello_class = getattr(module, class_name)
hello = hello_class('Hello world')

Werkzeug 包(Flask 使用)在此处提供了有用的功能:werkzeug.utils.import_string() 动态导入 对象

from werkzeug.utils import import_string

object_name = 'controller.{}:Example'.format(file)
hello_class = import_string(object_name)

这封装了上面的过程。

您需要非常小心接受来自网络请求的名称并将其用作模块名称。请务必清理 file 参数,并且只允许使用字母数字来防止使用相对导入。

您可以在此处使用werkzeug.utils.find_modules() function 来限制file 的可能值:

from werkzeug.utils import find_modules, import_string

module_name = 'controller.{}'.format(file)
if module_name not in set(find_modules('controller')):
    abort(404)  # no such module in the controller package

hello_class = import_string(module_name + ':Example')

【讨论】:

  • 嗯,不知道 importlib - 我刚学到一些新东西 :)
  • 这正是我想要的。谢谢!
  • 我必须同意@Martijn Pieters 的观​​点——这听起来像是在网络应用程序中做的冒险。您确定您的情况需要这样做吗?
  • @LukasKas:我记得 Werkzeug 有一些实用功能可以在这里提供帮助;已添加。
【解决方案2】:

我觉得你可能没有把目录加到文件里,把下面的代码加到前面的python程序里

# Add another directory
import sys
sys.path.insert(0, '/your_directory')

from Example import Example

【讨论】:

  • 是的,但我试图动态地做到这一点,不知道类或文件名
  • 尝试import os并通过os.listdir('./')获取所有子目录,迭代导入所有子目录
【解决方案3】:

您可以通过两种方式在 Python 中进行导入:

import example

e = example.Example('hello world')

from example import Example

e = Example('hello world')

【讨论】:

  • 当然,但是 OP 正在尝试使用 dynamic 导入。
  • 也许吧,但他没有写那个,他还说他几天前才开始使用 python。我更愿意假设从基础开始
  • 来自comment an another answer是的,但我尝试动态执行,不知道类或文件名
  • 是的,你是对的 - 但我写答案时没有这些信息:p
  • 嗯,__import__() 与从 URL 中获取的变量一起使用也是一个很大的提示。
猜你喜欢
  • 2021-12-30
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
相关资源
最近更新 更多