Доступ к модулю Python завершается неудачно, хотя его пакет импортирован - PullRequest
3 голосов
/ 13 апреля 2010

Иерархия каталогов моего проекта 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/.* отправляется в файл urls.py, который находится в / devices:

# ...
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?), Которую я допустил и, по-видимому, не вижу. Если нет, то читайте дальше. В любом случае, спасибо за чтение этого длинного поста!


Изоляция проблемы

1-й тест

Это работает, если я предоставляю функции представления в виде строк:

(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 *, однако, также не работает и приводит к тому же сообщению об ошибке.


2-й тест

Я создал файл test.py в / devices:

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, попытка from view.interaction import geraete, geraetegruppen, geraetemodelle в test.py приводит к ImportError: No module named view.interaction на этот раз.


3-й тест

Я запустил оболочку Django:

$ 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 ]

3 голосов
/ 13 апреля 2010

Когда модули находятся в пакетах и ​​вы импортируете пакет, Python не импортирует автоматически все модули в пакете. Что-то в вашей программе должно импортировать модули, которые вы хотите использовать. Это может быть ваш urls модуль:

import views.interaction.gaerete

или, если вы хотите, чтобы interaction.garaete всегда был доступен при импорте interaction, это может быть interaction/__init__.py:

import gaerete
0 голосов
/ 13 апреля 2010

Вам следует явно импортировать подмодули, если они не импортированы в файл __init__.py:

import interaction.geraete
0 голосов
/ 13 апреля 2010

Когда вы говорите

import devices.views.interaction

и позже

interaction.geraete

Python ищет geraete в модуле __init__.py в пакете взаимодействия.

Если вы хотите посмотреть, как это работает, вы можете явно указать import geraete в модуле __init__.py.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...