Как импортировать из одноуровневой директории в python3? - PullRequest
3 голосов
/ 06 марта 2019

У меня следующая файловая структура:

bot
├── LICENSE.md
├── README.md
├── bot.py # <-- file that is executed from command line
├── plugins
│   ├── __init__.py
│   ├── debug.py
│   └── parsemessages.py
├── helpers
│   ├── __init__.py
│   ├── parse.py
│   └── greetings.py
└── commands
    ├── __init__.py
    └── search.py

bot.py, при запуске из командной строки загружается во все в каталоге plugins.

Я хочу plugins/parsemessages.py для импорта parse из каталога helpers, поэтому я делаю это:

# parsemessages.py
from ..helpers import parse
parse.execute("string to be parsed")

Я запускаю python3 bot.py из командной строки.

Я получаю следующую ошибку:

File "/home/bot/plugins/parsemessages.py", line 2, in <module>
  from ..helpers import parse
ValueError: attempted relative import beyond top-level package

Поэтому я меняю две точки на одну:

# parsemessages.py
from .helpers import parse
parse.execute("string to be parsed")

... но я получаю еще одну ошибку:

File "/home/bot/plugins/parsemessages.py", line 2, in <module>
  from .helpers import parse
ImportError: No module named 'plugins.helpers'

Как я могу получить этот импортна работу?

Стоит отметить, что я не пытаюсь сделать пакет здесь, это просто обычный скрипт.При этом, я не хочу возиться с sys.path - я хочу, чтобы это было чисто для использования.

Кроме того, я хочу, чтобы parse был импортирован как parse - так что дляВ примере выше я должен набрать parse.execute(), а не execute().

Я нашел этот пост и этот пост , но они начинаются с файла, который довольноглубоко в файловой структуре (мой справа вверху).Я также нашел этот пост , но, похоже, речь идет о пакете, а не о обычном .py.

Какое здесь решение?

1 Ответ

1 голос
/ 06 марта 2019

Вы можете удалить точки, и это должно сработать:

# parsemessages.py
from helpers import parse
parse.execute("string to be parsed")

Это, вероятно, ваше лучшее решение, если вы действительно не хотите делать из него пакет.Вы также можете вложить весь проект на один каталог глубже и назвать его как python3 foo/bot.py.

Объяснение:

Когда вы не работаете с реально установленным пакетоми просто импортируя содержимое относительно вашего текущего рабочего каталога, все в этом каталоге считается пакетом верхнего уровня.В вашем случае bot, plugins, helpers и commands являются пакетами / модулями верхнего уровня.Ваш текущий рабочий каталог сам по себе , а не пакет .

Так что, когда вы делаете ...

from ..helpers import parse

... helpersсчитается пакетом верхнего уровня, поскольку он находится в вашем текущем рабочем каталоге, и вы пытаетесь импортировать его на один уровень выше этого уровня ( из вашего текущего рабочего каталога , самого , которыйэто не пакет).

Когда вы делаете ...

from .helpers import parse

... вы импортируете относительно plugins.Так что .helpers преобразуется в plugins.helpers.

Когда вы делаете ...

from helpers import parse

... он находит helpers как пакет верхнего уровня, потому что он находится в вашем текущемрабочий каталог.

...