У меня есть модуль с именем spellnum
. Его можно использовать в качестве утилиты командной строки (он имеет блок if __name__ == '__main__':
) или импортировать как стандартный модуль Python.
Модуль определяет класс с именем Speller
, который выглядит следующим образом:
class Speller(object):
def __init__(self, lang="en"):
module = __import__("spelling_" + lang)
# use module's contents...
Как видите, конструктор класса загружает другие модули во время выполнения. Эти модули (spelling_en.py
, spelling_es.py
и т. Д.) Расположены в том же каталоге, что и сам spellnum.py
.
Помимо spellnum.py
, существуют другие файлы с функциями и классами утилит. Я хотел бы скрыть эти файлы, так как я не хочу показывать их пользователю, и поскольку плохая идея - загрязнять каталог lib в Python случайными файлами. Единственный способ добиться этого, о котором я знаю, - это создать пакет.
Я придумал этот макет для проекта (вдохновленный этим замечательным учебником ):
spellnum/ # project root
spellnum/ # package root
__init__.py
spellnum.py
spelling_en.py
spelling_es.py
squash.py
# ... some other private files
test/
test_spellnum.py
example.py
Файл __init__.py
содержит одну строку:
from spellnum import Speller
Учитывая это новое расположение, код для динамической загрузки модуля должен был быть изменен:
class Speller(object):
def __init__(self, lang="en"):
spelling_mod = "spelling_" + lang
package = __import__("spellnum", fromlist=[spelling_mod])
module = getattr(package, spelling_mod)
# use module as usual
Итак, с этим макетом проекта можно сделать следующее:
Успешно import spellnum
внутри example.py
и используйте его как простой модуль:
# an excerpt from the example.py file
import spellnum
speller = spellnum.Speller(es)
# ...
import spellnum
в тестах и запустите эти тесты из корня проекта следующим образом:
$ PYTHONPATH="`pwd`:$PYTHONPATH" python test/test_spellnum.py
проблема
Я не могу выполнить spellnum.py
напрямую с новым макетом. Когда я пытаюсь, это показывает следующую ошибку:
Traceback (most recent call last):
...
File "spellnum/spellnum.py", line 23, in __init__
module = getattr(package, spelling_mod)
AttributeError: 'module' object has no attribute 'spelling_en'
Вопрос
Каков наилучший способ организовать все файлы, необходимые для работы моего модуля, чтобы пользователи могли использовать модуль как из командной строки, так и из своего кода Python?
Спасибо!