2016-07-11 1 views
0

Я нахожусь в разгаре пакета python и смущен по всем аспектам упаковки.Нужна правильная структура каталогов для пакетов python и рекомендации по хорошему дизайну API

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

SamplePackage/ 
- setup.py 
- README.rst 
- LICENSE.rst 
- sampledir/ 
    -__init__.py 
    -sample.py 
    -utils.py 

В настоящее время __init__ и setup не заселены. sample.py - файл, который любой пользователь пакета захочет импортировать. Он содержит api в виде различных функций: foo1, foo2.

utils.py содержит вспомогательные вымыслы для smaple.py. Последнее содержит заявление import utils

Любые скрипты, размещенные в каталоге sampledir может легко import sample и использовать вымыслы в sample.foo1(). Выйдя из этого каталога, я могу позвонить import sampledir, но не import sample, который ожидается. Поэтому мне нужно сделать from sampledir import sample. Это приводит к ошибке на import utils линии в sample.py

ImportError: No module named 'utils' 

В некоторых местах я видел import .utils файлов в одном каталоге. Но когда я пытаюсь это сделать, это приводит к синтаксической ошибке.

Почему я не могу импортировать sample.py со стороны sampledir?

Кроме того, что структура каталогов позволит пользователям, которые установили пакет просто быть в состоянии назвать import sample с последующим sample.foo1() и не должны делать from sampledir import sample или import sampeldir.sample. Например, при использовании библиотеки HTTP requests просто нужно ее импортировать и вызвать requests.get(url). requests.requests.get('url') не требуется, как в urllib. Какое правильное назначение и расположение каталогов для достижения этого, если я хочу, чтобы пакет был назван sample?

+0

Если вы хотите, чтобы это было как 'запросы', [идите и смотрите' запросы'] (https://github.com/kennethreitz/requests)! – jonrsharpe

ответ

0

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

arbitrary_name_of_project/ 
- setup.py 
- README.rst 
- LICENSE.rst 
- package_name/ 
    -__init__.py 
    -sample.py 
    -utils.py 

питона «отмечен» по наличию файла __init__.py. Python на своем PYTHONPATH и ищет все каталоги с файлом __init__.py (просто говоря, это на самом деле намного сложнее). Это пакеты, которые можно импортировать во время выполнения.

В нашем случае только package_name каталог будет установлен где-то до PYTHONPATH.Таким образом, после установки (через setup.py и disutils или setuptools), вы можете ввести

import package_name 

Теперь вы можете называть произвольный класс или функцию или любой из любого модуля в этом пакете, как

package_name.sample.func1() 

Если вы не хотите печатать package_name.sample в вызове, вы можете поместить эту строку в __init__.py

from .sample import func1 

Затем функция «func1» будет помещена в ваше глобальное пространство имен во время «времени импорта». Это происходит, когда в вашей программе выполняется import package_name. Эта тайна может быть решена тем фактом, что файл __init__.py выполняется каждый раз, когда импортируется пакет.

Иногда необходимо больше плюнуть на конструкцию. У вас могут быть «вложенные» пакеты (т. Е. Пакеты в пакете, которые необходимо импортировать). Существуют также пакеты пространства имен, где вы можете «плюнуть» на один пакет из числа каталогов. Мир разнообразен. :)

Отказ

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