2013-07-26 3 views
3

В проекте Django, у меня есть структура каталогов, которая выглядит примерно так:Относительный импорт создает другой объект класса?

project/ 
├╴module_name/ 
│ ├╴dbrouters.py 
│ ... 
... 

В dbrouters.py я определяю класс, который начинается так:

class CustomDBRouter(object): 
    current_connection = 'default' 
    ... 

Идея заключается в том, чтобы иметь маршрутизатор базы данных, который устанавливает соединение для использования в начале каждого запроса, а затем использует это соединение для всех последующих запросов к базе данных, аналогично тому, что описано в Django docs for automatic database routing.

Все работает отлично, за исключением того, что когда я хочу импортировать CustomDBRouter в сценарий, Мне нужно использовать абсолютный путь, иначе произойдет что-то странное.

Скажем, в одной части приложения, CustomDBRouter.current_connection изменяется:

import project.module_name.dbrouters.CustomDBRouter 
... 
CustomDBRouter.current_connection = 'alternate' 

В другой части приложения (предположим, что он выполняется после кода выше), я использую относительный импорт вместо:

import .dbrouters.CustomDBRouter 
... 
print CustomDBRouter.current_connection # Outputs 'default', not 'alternate'! 

Я смущен, почему это происходит. Является ли Python созданием нового объекта класса для CustomDBRouter, потому что я использую другой путь импорта?

Бонусные баллы: Есть ли лучший способ реализовать свойство «глобального» класса?

+1

Дополнительная информация: https://ncoghlan_devs-python-notes.readthedocs.org/en/latest/python_concepts/import_traps.html – torek

ответ

0

Оказывается, проблема была быть вызвана несколькими строками в другом файле:

PROJECT_ROOT = '/path/to/project' 
sys.path.insert(0, '%s' % PROJECT_ROOT) 
sys.path.insert(1, '%s/module_name' % PROJECT_ROOT) 

Файлы, которые были ссылающихся .dbrouters были импортированы с помощью «быстрого» путь (например, import views вместо import module_name.views) ,

0

Это зависит от того, как выполняется этот сценарий. Когда вы используете относительный импорт, вы должны убедиться, что имя скрипта, в котором находится импорт, имеет атрибут __name__, отличный от __main__. Если это так, import .dbrouters.CustomDBRouter будет import __main__.dbrouters.CustomDBRouter.

Я нашел это here.