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

#python #file-structure

#python #структура файла

Вопрос:

При написании кода я часто сталкиваюсь с проблемой устранения тривиальных зависимостей. Например, давайте возьмем макет объекта memoizer, который я недавно написал. Моя структура каталогов выглядит следующим образом:

 memoizer/
  memoizer.py
  tests.py
  strategies/
    __init__.py
    perfect.py
    mru.py
    queue.py
README
  

Проблема, в частности, в mru.py . mru.py содержит класс MRU, который использует очередь, определенную в queue.py . Очевидно, однако, что очередь не является стратегией для memoizer, и нет никакого смысла помещать ее в strategies .

Одна из моих идей заключалась в том, чтобы настроить мой код так, чтобы он выглядел примерно так:

 memoizer/
  memoizer.py
  tests.py
  strategies/
    __init__.py
    perfect.py
    mru/
      __init__.py
      mru.py
      queue.py
README
  

Проблема с этой настройкой заключается в том, что теперь пользователь должен знать, что mru находится в подпакете.

Другая идея заключалась в том, чтобы организовать структуру следующим образом:

 memoizer/
  memoizer.py
  tests.py
  strategies/
    __init__.py
    perfect.py
    mru.py
    dependencies/
      __init__.py
      queue.py
README
  

Это решило бы мою проблему, но интуитивно кажется, что это неправильный способ сделать это.

Как правильно организовать мои файлы, чтобы учесть это несоответствие?

Ответ №1:

Я бы предложил вариант второй структуры:

 memoizer/
  memoizer.py
  tests.py
  strategies/
    __init__.py
    perfect.py
    mru/
      __init__.py <- This is what used to be mru.py
      queue.py
README
  

Тогда пользователь может просто import memoizer.strategies.mru .

Это быстрый и простой способ сделать это. Тем не менее, вы могли бы сохранить исходный mru.py файл и предоставить элементы из него в своем __init__.py подобном:

 import mru as _mru

SomeClass = _mru.SomeClass
# etc...
  

Комментарии:

1. Можете ли вы подробнее рассказать об использовании init.py чтобы разоблачить мру? Кажется, я не могу понять из документации, как именно это работает, за исключением случая с импортом из x * .

2. По сути, python обрабатывает module/__init__.py файл так же, как и файл module.py . Самый простой способ сделать это — просто переименовать mru.py __init__.py внутри mru папки.

3. Итак, я получаю следующее при использовании интерпретатора из / memoizer. >>> from strategies.mru import MRU Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name MRU >>> from strategies.mru.mru import MRU Я что-то недопонимаю? РЕДАКТИРОВАТЬ: Неважно — ваши правки прояснили мое замешательство.

4. from strategies.mru.mru import MRU сообщает python предположить, что существует strategies/mru/mru.py strategies/mru/mru/__init__.py файл or с MRU определенным в нем именем. Если вы переименовали свой mru.py файл в __init__.py , тогда вам следует просто использовать from strategies.mru import MRU