尽管导入了包,但访问Python模块失败

时间:2010-04-13 08:55:25

标签: python import package

我的Django项目的目录层次结构如下所示:

+ pybsd
|---+ devices
    |---+ templates
    |---+ views
        |---+ interaction
            |---- __init__.py
            |---- geraete.py
            |---- geraetemodelle.py
            |---- geraetegruppen.py
        |---- __init__.py
        |---- ajax.py
        |---- html.py
        |---- misc.py
    |---- __init__.py
    |---- urls.py
|---- __init__.py
|---- urls.py

(请原谅德语名称。我不想在这里更换它们,因为在尝试你希望提出的解决方案并回答你的问题时会增加另一个可能的错误来源。)

每个http://URL/devices/。*的请求都会被发送到/ devices中的urls.py文件:

# ...
from views import html, ajax, misc, interaction

urlpatterns = patterns('', 
    # ...
    (r'^ajax/update/(?P<table>[a-z_]+)$', ajax.update),
    (r'^ajax/delete/(?P<table>[a-z_]+)$', ajax.delete),
    (r'^ajax/select_options/(?P<table>[a-z_]+)$', ajax.select_options),

    (r'^interaction/geraete/info/(?P<geraet>\d+)$', interaction.geraete.info),
    (r'^interaction/geraete/delete/(?P<geraet>\d+)?$', interaction.geraete.delete),
    (r'^interaction/geraetemodelle/delete/(?P<geraetemodell>\d+)?$', interaction.geraetemodelle.delete),
    (r'^interaction/geraetegruppen/delete/(?P<geraetegruppe>\d+)?$', interaction.geraetegruppen.delete),
    # ...
)

除引用交互包之外,所有URL定义都有效。我经常收到以下错误:

File "/home/simon/projekte/pybsd/../pybsd/devices/urls.py", line 33, in `<module>`
  (r'^interaction/geraete/info/(?P<geraet>\d+)$', interaction.geraete.info),
AttributeError: 'module' object has no attribute 'geraete'

我仔细检查了__init__.py文件中没有包含任何内容。

也许你已经发现了我所犯的(Python或Django相关的?)错误,显然无法看到。如果没有,请继续阅读。无论如何,感谢您阅读这篇长篇文章!


隔离问题

第一次测试

如果我将视图函数提供为字符串,那么它是有效的:

(r'^interaction/geraete/info/(?P<geraet>\d+)$', 'devices.views.interaction.geraete.info'),
(r'^interaction/geraete/delete/(?P<geraet>\d+)?$', 'devices.views.interaction.geraete.delete'),
(r'^interaction/geraetemodelle/delete/(?P<geraetemodell>\d+)?$', 'devices.views.interaction.geraetemodelle.delete'),
(r'^interaction/geraetegruppen/delete/(?P<geraetegruppe>\d+)?$', 'devices.views.interaction.geraetegruppen.delete'),

...或在导入中添加另一行:

from views.interaction import geraete, geraetemodelle, geraetegruppen

然而,使用from views.interaction import *也不起作用,并导致相同的错误消息。


第二次测试

我在/ devices:

中创建了一个文件test.py.
from views import interaction
print dir(interaction)

输出:

simon@bsd-simon:~/projekte/pybsd/devices$ python test.py
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

同样,我没有在交互包中创建模块的迹象(geraete.py,geraetemodelle.py,geraetegruppen.py)。

与urls.py不同,这次在test.py中尝试from view.interaction import geraete, geraetegruppen, geraetemodelle会产生ImportError: No module named view.interaction


第3次测试

我启动了Django shell:

$ python manage.py shell
>>> import devices.views.interaction.geraete
>>> dir(devices.views.interaction.geraete)
['Abteilung', 'Auftrag', 'Auftragsvorlage', 'Geraet', 'Geraetegruppe', 'Geraetemodell', 'HttpResponse', 'HttpResponseBadRequest', 'HttpResponseRedirect', 'Raum', 'Standort', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'delete', 'info', 'models', 'move', 'render_to_response']
>>> 

$ python manage.py shell
>>> from devices.views.interaction import geraete
>>> dir(geraete)
['Abteilung', 'Auftrag', 'Auftragsvorlage', 'Geraet', 'Geraetegruppe', 'Geraetemodell', 'HttpResponse', 'HttpResponseBadRequest', 'HttpResponseRedirect', 'Raum', 'Standort', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'delete', 'info', 'models', 'move', 'render_to_response']
>>> 

$ python manage.py shell
>>> import devices.views.interaction
>>> devices.views.interaction.geraete
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'module' object has no attribute 'geraete'
>>> dir(devices.views.interaction)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

3 个答案:

答案 0 :(得分:3)

当模块存在于软件包中并导入软件包时,Python不会自动导入软件包中的所有模块。程序中的某些东西需要导入您想要使用的模块。这可以是您的urls模块:

import views.interaction.gaerete

或者,如果您希望interaction.garaete在导入interaction时始终可用,则可以是interaction/__init__.py

import gaerete

答案 1 :(得分:0)

当你说

import devices.views.interaction

以后

interaction.geraete

Python在交互包中的 __init__.py 模块中查找 geraete

如果您希望这样做有效,可以在import geraete模块中明确包含__init__.py

答案 2 :(得分:0)

如果子模块未导入__init__.py文件,则应明确导入子模块:

import interaction.geraete