Python意外的导入行为

时间:2016-02-18 22:21:25

标签: python django python-2.7 python-import

我正在尝试构建一个视图,其中表单是基于表单slug动态加载的,可用的表单是在这样的元组列表中定义的,这是为了加快“框架式”中新表单的开发“方式:

#installed_io.py
forms = [("json",JsonForm),("csv",CsvForm),....]

froms像往常一样在forms.py模块中定义。

from django import forms

class FileForm(BaseDatasetForm):
    file = forms.FileField(label="Opcion 1: Seleccione un archivo", required=False)
    text = forms.CharField(widget=forms.Textarea, label="Opction 2: Introduzca el contenido en este campo", required=False)

utils.py定义了动态选择Form类的函数:

from installed_io import installed_inputs    

def get_input_form(slug):
    for entry in installed_inputs:
        if entry[0] == slug:
            return entry[1]
    raise NotImplementedError("The required form is not implemented or missing from the installed inputs")

视图在我的django app的views.py模块中定义:

#views.py
from utils import get_input_form

@login_required
def add(request, slug):
    InputForm = get_input_form(slug)
    if request.method == "POST":
        form = InputForm(request.POST, request.FILES)
        if form.is_valid():
            object_id = form.save()
            messages.success(request, "Dataset created")
            return redirect(reverse("input:dataset", args=[str(object_id.inserted_id)]))
    else:
        form = InputForm()
    return render(request, "datasets/add-form.html", {"form":form})

但是我收到了这个导入错误:

python manage.py runserver
Unhandled exception in thread started by <function wrapper at 0x7fe9c465c398>
Traceback (most recent call last):
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
    autoreload.raise_last_exception()
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
    six.reraise(*_exception)
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/analysis/models.py", line 2, in <module>
    from ..input.forms import SOURCES
  File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/forms.py", line 2, in <module>
    from utils import save_dataset
  File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/utils.py", line 2, in <module>
    from installed_io import installed_inputs
  File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/installed_io.py", line 1, in <module>
    from forms import FileForm
ImportError: cannot import name FileForm

我尝试了什么:

  • 使用绝对路径更改导入语句
  • 删除pyc文件
  • 使用点符号导入模块
  • 尝试在 init .py
  • 上保存installed_input列表
  • 只将所有代码移动到views.py文件,但我发现这个解决方案非常单一且非pythonic。

1 个答案:

答案 0 :(得分:0)

根据对原始帖子的评论,我对我的代码进行了以下更改:

而不是在installed_io模块上导入类我使用了字符串:

#installed_io.py
forms = [("json","JsonForm"),("csv","CsvForm"),....]

然后我更改了utils.py以从字符串中导入类:

from installed_io import installed_inputs    

def get_input_form(slug):
    for entry in installed_inputs:
        if entry[0] == slug:
            module = importlib.import_module("tensorflow_board_django.io.forms")
            class_name = entry[1]
            return getattr(module, class_name)
    raise NotImplementedError("The required form is not implemented or missing from the installed inputs")