如何导入一个模糊名称的特定模块?
这个问题发生在Django的环境中,但并不是专门针对Django的。
我想把我的大文件urls.py
拆分成更小、更易管理的部分(比如应用包含、第三方模块、搜索、管理、开发等等)。所以我现在不再使用urls.py
,而是用一个urls/
目录,里面有一个urls/__init__.py
,内容大概是这样的:
import admin
urlpatterns += admin.urlpatterns
现在我遇到了第三方模块的问题。比如,我想覆盖一些django-messages
的URL和视图,所以我把这些内容放到了urls/messages.py
里。结果发现,我无法导入django-messages
的视图,因为
from messages.views import inbox
在urls/messages.py
中,Python会先尝试从本地目录导入,找到了一个messages
模块,但却无法导入messages.views
,因为urls/messages/views.py
显然是不存在的。我不想把我的模块重命名成像urls.messages_urls
这样的名字,但我也没找到办法明确告诉Python去导入另一个messages.views
。我也不想通过字符串来指定我导入的视图,尽管在Django中是可以这样做的。
我该如何干净利落地解决这个问题呢?
3 个回答
你试过这样做吗:
from django.contrib.messages.views import inbox
这个还没测试过,不过我觉得完整的导入应该能按预期工作。
对于那些找不到解决办法的人,我遇到了模糊的导入错误。比如,在一个Django项目中,假设我的文件结构是这样的:
- tax模块
- models模块
- init.py
- tax.py
- foo.py
- models模块
在init.py文件中,我想导入tax.models.tax.Tax类。所以我写了:
from tax.models.tax import Tax
但是Python找不到正确的导入(它在tax.models里面寻找models),于是就报错了:
ImportError: No module named models
你应该明白,这其实跟相对导入有关。Python首先会在当前模块中查找。如果你导入的第一个部分在当前模块中存在,它就会失败。
这个问题在Python 2.5中得到了修复(在Python 3.0中可能已经成为默认行为),你只需要在你的绝对导入之前加上:
from __future__ import absolute_import
想了解更多信息,可以查看Python 2.5引入的绝对导入。
这样做是不对的。
Django有一种方法可以把urls.py拆分成多个文件,这个方法就是使用include()
。你可以把每个应用的链接放在它自己的urls.py文件里,然后再把这些文件包含到主文件中。