Проблема с питоном и __import__ - PullRequest
1 голос
/ 27 августа 2009

Извините за общее название, изменит его, как только я пойму источник моей проблемы У меня есть следующая структура:

foo/
foo/__init__.py
foo/bar/
foo/bar/__init__.py
foo/bar/some_module.py

Когда я пытаюсь импортировать some_module, сделав так:

from foo.bar import some_module

это работает как шарм. Но это не очень хорошо для меня, так как я знаю только имя модуля для импорта во время выполнения. так что если я попробую:

from foo.bar import *
mod=__import__('some_module')

Я получаю ошибку. Я делаю что-то неправильно? Есть лучший способ сделать это? и почему это происходит?

Почему это? Я не совсем уверен, что полностью понимаю концепцию пакетов Python. Я думал, что они были эквивалентны пакетам Java и, таким образом,

Ответы [ 3 ]

7 голосов
/ 27 августа 2009

Я считаю, что правильный способ сделать это:

mod = __import__('foo.bar', fromlist = ['some_module'])

Таким образом, даже часть 'foo.bar' может быть изменена во время выполнения. В результате some_module будет доступно как mod.some_module; используйте getattr, если хотите, в отдельной переменной:

the_module = getattr(mod, 'some_module')
1 голос
/ 27 августа 2009
from foo.bar import *

- плохая практика, поскольку она импортирует some_module в глобальную область.

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

import foo.bar
mod = getattr(foo.bar, 'some_module')

Легко показать, что этот подход работает:

>>> import os.path
>>> getattr(os.path, 'basename')
<function basename at 0x00BBA468>
>>> getattr(os.path, 'basename\n')
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    getattr(os.path, 'basename\n')
AttributeError: 'module' object has no attribute 'basename
'

P.S. Если вы все еще заинтересованы в использовании своего вида заявления на импорт. Вам нужен eval:

from foo.bar import *
eval('some_module')

Чтобы уточнить: использовать не только * - импорт - это даже хуже в сочетании с eval Так что просто используйте getattr, он предназначен именно для таких ситуаций, как ваша.

0 голосов
/ 27 августа 2009

Из документов :

Прямое использование __import__() редко, за исключением случаев, когда вы хотите импортировать модуль, имя которого известно только во время выполнения.

Однако точечная запись должна работать:

mod = __import__('foo.bar.some_module')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...