Модули Python против пакета - PullRequest
0 голосов
/ 11 июня 2019

Запуск Python 3.7.3 на Mac и Windows, а также решение другой моей проблемы:

Невозможно найти субмодуль в пакете на одном ПК, но не на другом ПК

Я прочитал десяток постов, касающихся пакетов и модулей, таких как этот:

Может кто-нибудь объяснить __all__ на Python?

Однако я все еще получаю неожиданные результаты.

У меня есть структура пакета

pypkg/
    __init__.py
    src/
        __init__.py
        app.py
    util/
        __init__.py
        util.py

src / app.py работает следующим образом

# app.py

from pprint import pprint
import sys
pprint(sys.path, indent=4)

from util import *


def main():
    print('this is app.')
    util.func()
    pprint(sys.path, indent=4)


if __name__ == '__main__':
    main()

util / util.py выглядит следующим образом

# util.py

def func():
    print('this is func from util.')

И я ожидаю, что, сидя под корнем проекта, т.е. /path/to/pypkg/, я смогу позвонить:

python src/app.py

И запустить его без проблем.

Однако, это дает мне:

ModuleNotFoundError: No module named 'util'

Затем я переключаюсь на работу:

python -m src.app

На этот раз я получаю:

NameError: global name 'util' is not defined

Наконец, я вручную добавляю следующее к util/__init__.py:

__all__ = ['util']

На этот раз все в порядке.

Мои предположения из опыта:

  1. Зависимость пакета будет работать только при запуске Python с опцией -m.
  2. Мое первоначальное впечатление, что __init__.py может быть пустым, является заблуждением. Если бы я использовал from <package> import *, то __init__.py ДОЛЖЕН определить __all__.
  3. Текущий рабочий каталог имеет значение при использовании системы пакетов.

Мой вопрос: все мои предположения верны?

Если все мои предположения верны, то было бы неудобно использовать систему пакетов с базой кода, которая смешивает код приложения и код зависимости, где в общем случае вы хотите перейти в командную строку, где бы вы ни находились, и просто вызвать python random/relative/path/to/script.py. Но пакеты с этой парадигмой плохо работают.

Теперь мои следующие вопросы:

Должен ли я использовать пакет таким образом? Лучше всего придерживаться старого доброго sys.path взлома, если сам «пакет» содержит код приложения?

...