我试图在url路由的基础上导入Flask app上的文件。几天前我开始编写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
谢谢大家!
答案 0 :(得分:5)
__import__
返回新导入的模块;该模块中的名称 not 已添加到您的全局变量中,因此您需要将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')
答案 1 :(得分:0)
我认为你可能不会将目录添加到文件中,将以下代码添加到上一个python程序
中# Add another directory
import sys
sys.path.insert(0, '/your_directory')
from Example import Example
答案 2 :(得分:0)
您可以通过两种方式在Python中进行导入:
import example
e = example.Example('hello world')
或
from example import Example
e = Example('hello world')