Я записал модуль Python, и у меня есть две версии: чистая реализация Python и расширение C. Я записал __init__.py
файл так, чтобы это попыталось импортировать расширение C, и если это перестало работать, это импортирует чистый код Python (который разумен?).
Теперь, я хотел бы знать то, что является лучшим способом распределить этот модуль (например, запись setup.py
) таким образом, это может легко использоваться людьми с или без средства, чтобы создать, или использовать, расширение C, только путем выполнения:
python setup.py install
Мой опыт ограничен, но я вижу два возможных случая:
(это разумно?).
Ага, совершенно разумно.
Чтобы поймать «неподходящий случай компилятора C»: вызов setup (...)
выполнит sys.exit в случае проблем. Итак, сначала попробуйте с параметром ext_modules
, установленным по желанию, в try
:
try:
setup(..., ext_modules=...)
except SystemExit: ...
и в предложении except
вызовите setup ( ...)
снова без ext_modules
(поэтому он отказывается от сборки и установки расширений). Пользователь, выполняющий установку, по-прежнему будет видеть такие сообщения, как «невозможно выполнить gcc-4.0: нет такого файла или каталога», но вы можете соответствующим образом добавить свои собственные сообщения, чтобы проинформировать пользователя, что это не имеет большого значения и что вы пытаетесь снова без модули расширения.
Для поддержки реализаций, отличных от CPython, в вашем setup.py
вы можете протестировать sys.version
(я не уверен, какое значение будет для каждой реализации, отличной от CPython. , но в IronPython есть подстрока 'IronPython'
, например), чтобы даже не пытаться использовать часть ext_modules
. Если вы пропустите какую-то такую реализацию в своих проверках, команда try / except, вероятно, все равно должна уловить большинство других, просто с небольшим количеством потраченной впустую работы ;-).
«пытается импортировать расширение C, и если это не удается, импортирует чистый код Python (это разумно?)»
Почти. Прочтите о cStringIO
и StringIO
. Также прочтите о cPickle
и Pickle
. Также прочтите о cElementTree
и ElementTree
.
Если версия C не может быть создана, это один из вариантов использования. Версия на чистом Python - единственная доступная.
Однако, если C-версия может быть построена, у меня все еще есть веские причины отказаться от нее. В первую очередь, я бы подумал об отказе от версии C, потому что она может не допускать глубину подкласса, которая мне нужна для моего приложения.
Я не хочу, чтобы меня заставляли использовать версию C только потому, что у меня был правильный компилятор. Я предпочитаю принимать эти решения самостоятельно.
Следовательно, мне не нравится идея о том, что какая-то часть вашего модуля будет принимать мои архитектурные решения за меня. Я предпочитаю выбирать, что импортировать. Если версии C не существует, это не меняет моего процесса принятия решения, потому что я все еще могу создавать подклассы чистой версии Python.
Итог. Меньше автоматизируйте. Предоставьте два модуля. Я предпочитаю выбирать, какой из них импортировать.
Согласно документации для Planar , вы можете создать файл setup.py
для создания расширений C как обычно, а затем:
Для сборки и установки Planar из исходного дистрибутива или репозитория используйте:
python setup.py install
Чтобы установить только модули чистого Python без компиляции, используйте:
python setup.py build_py install --skip-build