Как сделать импорт из каталога уровнем выше?

Рейтинг: 0Ответов: 2Опубликовано: 26.01.2023

У меня есть файлы

abc/bot.py
payment.py
bot.py

Я запускаю abc/bot.py и мне нужно импортировать payments.py, то есть каким-то образом перейдите в каталог выше. Я пытался

от.. импорт платежа
из ..импорт платежа отправить

Я получил сообщение об ошибке ImportError: предпринята попытка относительного импорта без известного родителя, и все. Что делать?

Ответы

▲ 0

Можно использовать os.chdir(path) чтобы указать точный путь/каталог который вам нужен

▲ 0

Костыльный способ: добавить внешнюю папку в переменную окружения PYTHONPATH, тогда можно будет из нее импортировать просто по имени:

abc/bot.py:

import sys
from pathlib import Path
# __file__ - путь текущего файла, из него получаем путь к директории выше
sys.path.append(str(Path(__file__).parent.parent))  
import payment

Другой вариант: считать, что вся папка, где лежит код - это пакет, и запускать код в ней как модуль.

Структура каталогов:

.
└── some_bot
    ├── abc
    │   └── bot.py
    ├── bot.py
    └── payment.py

Файл some_bot/abc/bot.py:

from ..payment import send
# Или from some_bot.payment import send

send()

Файл some_bot/payment.py:

def send():
    print("send something")

Из командной строки, находясь в директории снаружи some_bot, запускаем:

> python3 -m some_bot.abc.bot
send something

Ключевое тут: чтобы работал абсолютный (from some_bot.payment import send) или относительный (from ..payment import send) импорт, код должен запускаться как пакет, снаружи пакета. Не двойным кликом по файлу abc/bot.py или командой python abc/bot.py, а через python с ключом -m, иначе будет ошибка ImportError (при относительном импорте - что не известен родительский пакет, при абсолютном - что пакет с таким именем не найден).

В целом, если положить снаружи пакета some_bot модуль python, и в нем прописать import some_bot.abc.bot, то это будет аналогично запуску python -m some_bot.abc.bot из командной строки.


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

Про пакеты можно почитать, например, тут: Пакеты Python — создание и доступ

Только я не добавлял файл __init__.py, есть отличия в пакетах с таким файлом и без него, но в данном случае это не критично.
Детально про __init__.py можно почитать тут: Is __init__.py not required for packages in Python.