Пакет Python как приложение и как библиотека - PullRequest
0 голосов
/ 12 декабря 2018

Я знаю, что такой вопрос уже существует, но я работаю над ним уже более часа и не могу заставить его работать вообще.

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

setup.py
/RecurrenceRelationSolver
-- __init__.py
-- RecurrenceRelation.py
-- RecurrenceRelationParser.py
-- RecurrenceRelationSolver.py
/tests
-- __init__.py
-- context.py
-- test_homogenous.py

Github здесь: https://github.com/rowanG077/RecurrenceRelationSolver

Мой __init__.py выглядит так, поскольку я хочу разрешить другим людям импортировать эти классы:

from .RecurrenceRelation import RecurrenceRelation
from .RecurrenceRelationParser import RecurrenceRelationParser

В моем случае RecurrenceRelationSolver.py не содержит классов, но что-то вроде этого:

from . import RecurrenceRelationParser
from . import RecurrenceRelation

def main():
   ...

if __name__ == '__main__':
    main()

Тогда в моих модульных тестах __init__.py пуст, а в context.py у меня есть:

# -*- coding: utf-8 -*-
import sys
import os

sys.path.insert(0, os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..')))

from RecurrenceRelationSolver import RecurrenceRelation, RecurrenceRelationParser

Как это структурировано сейчас, я могу успешно запустить модульные тесты, однако, когда я нахожусь в каталоге RecurrenceRelationSolver и запускаю python RecurrenceRelationSolver.py, он не работает со следующим сообщением:

from . import RecurrenceRelationParser
ImportError: cannot import name 'RecurrenceRelationParser'

Я не уверен, как это сделать, так как я никогда не делал такой модуль.Могу ли я в любом случае структурировать свои операции импорта, чтобы я мог продолжать использовать пакет как библиотеку и как непосредственно запускаемый?

Любая помощь приветствуется!

Я использую Python 3.6.

1 Ответ

0 голосов
/ 12 декабря 2018

Ваш код в порядке.Проблема в том, что вы пытаетесь запустить код неправильно.

Вам не нужно изменять sys.path для запуска ваших тестов (или вообще любой sys.path.insert(...) является запахом кода. В 99В% случаев есть лучшие альтернативы).

Вам следует запустить свои тесты из вне папки tests, чтобы пакет был доступен.Если вы используете такие инструменты, как py.test или nosetests, вы можете сказать им, где находится исходный код, и они позаботятся о том, чтобы соответствующим образом изменить PYTHONPATH.

Второе: это простонеправильно заходить в каталог пакетов и делать что-либо.Пакеты являются единицами, вам никогда не нужно заходить в них, чтобы что-то делать.

Чтобы правильно запустить скрипт, запустите его извне пакета, используя переключатель -m:

python3 -m RecurrenceRelationSolver.RecurrenceRelationSolver

В качестве альтернативыВы можете написать скрипт вне вашего пакета, который импортирует этот модуль и запускает основную функцию.Если вы используете setuptools в своем setup.py, вы можете использовать параметр entry_points для автоматического определения некоторых console_scripts.

...