Не непосредственно ответ на Ваш вопрос, но необходимо рассмотреть именование его __version__
, не version
.
Это - почти квазистандарт. Много модулей в стандартном использовании библиотеки __version__
, и это также используется в партии из сторонних модулей, таким образом, это - квазистандарт.
Обычно, __version__
строка, но иногда это - также плавание или кортеж.
Редактирование: как упомянуто S.Lott (Спасибо!), PEP 8 говорит это явно:
Бухгалтерия Версии
, Если у Вас должна быть Подрывная деятельность, CVS или свернувшееся молоко RCS в Вашем исходном файле, делает это следующим образом.
__version__ = "$Revision: 63990 $" # $Source$
Эти строки должны быть включены после docstring модуля, перед любым другим кодом, разделенным пустой строкой выше и ниже.
необходимо также удостовериться, что номер версии соответствует формату, описанному в PEP 440 ( PEP 386 предыдущая версия этого стандарта).
Если это имеет значение, если Вы используете NumPy distutils, numpy.distutils.misc_util.Configuration
имеет make_svn_version_py()
метод, который встраивает число пересмотра в package.__svn_version__
в переменной version
.
Кажется, нет стандартного способа встроить строку версии в пакет Python. Большинство пакетов, которые я видел, использует некоторый вариант Вашего решения, т.е. любой
Встраивают версию в setup.py
и имеют setup.py
, генерируют модуль (например, version.py
) содержащий только информацию о версии, это импортируется Вашим пакетом, или
реверс: поместите информацию о версии в свой пакет сам и импортируйте что для установки версии в setup.py
Также стоящий замечания то, что, а также __version__
являющийся полустанд. в Python так __version_info__
, который является кортежем в простых случаях, как которые можно просто сделать что-то:
__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])
... и можно добраться эти __version__
строка из файла, или что бы то ни было.
лучшее решение я нашел, когда использование Мерзавца для VCS/SCM должно использовать setuptools
с pbr
расширение. Это позволит Мерзавцу быть Вашим основным источником истины для некоторых метаданных, включая версию, авторов, журналы изменений, и т.д., таким образом, у Вас не будет дублированной информации, которая выходит из синхронизации, и devs может работать непосредственно в Мерзавце.
setup.py
и setup.cfg
файл с метаданными , Поскольку PBR вытянет версию, автора, журнал изменений и другую информацию непосредственно от Вашего мерзавца repo, таким образом, много метаданных в setup.cfg
сможет быть не учтено и автоматическое сгенерированный.
PBR вытянет последнюю информацию в режиме реального времени с помощью setup.py
команды, например:
py setup.py --version
Это вытянет последнюю версию от мерзавца repo, на основе последней фиксации, которая была сделана. Это не обновляет версию в распределении все же. При создании распределения с setup.py
(т.е. py setup.py sdist
, например), тогда вся текущая информация будет извлечена и сохранена в распределении.
можно получить доступ к метаданным от текущей сборки в рамках сценариев Python в самом пакете. Для версии, например, существует несколько способов сделать это, я нашел до сих пор:
import pkg_resources # part of setuptools
# I don't like this one because the version method is hidden
v1 = pkg_resources.require("md2mat")[0].version
print('v1 {}'.format(v1))
# This is my favorite - the output without .version is just a longer string with
# both the package name, a space, and the version string
v2 = pkg_resources.get_distribution('md2mat').version
print('v2 {}'.format(v2))
from pbr.version import VersionInfo
# This one seems to be slower, and with pyinstaller makes the exe a lot bigger
v3 = VersionInfo('md2mat').release_string()
print('v3 {}'.format(v3))
можно поместить один из них непосредственно в Вашем __init__.py
, чтобы пакет извлек информацию о версии следующим образом, подобный некоторым другим ответам:
__all__ = (
'__version__',
'my_package_name'
)
import pkg_resources # part of setuptools
__version__ = pkg_resources.get_distribution("md2mat").version
Хотя это, вероятно, уже слишком поздно, есть немного более простая альтернатива предыдущему ответу:
__version_info__ = ('1', '2', '3')
__version__ = '.'.join(__version_info__)
(И было бы довольно просто преобразовать автоматически увеличивающиеся части номеров версий в строка с использованием str ()
.)
Конечно, из того, что я видел, люди склонны использовать что-то вроде ранее упомянутой версии при использовании __ version_info __
и как таковые сохранить его как кортеж целых чисел; однако я не совсем вижу в этом смысл, так как сомневаюсь, что есть ситуации, когда вы будете выполнять математические операции, такие как сложение и вычитание частей номеров версий, для любых целей, кроме любопытства или автоматического увеличения (и даже тогда, int ()
и str ()
могут использоваться довольно легко). (С другой стороны, есть вероятность того, что чей-то другой код ожидает числовой кортеж, а не строковый кортеж, и, таким образом, потерпит неудачу.)
Это, конечно, мое собственное мнение, и я с радостью хотел бы узнать мнение других об использовании числового кортежа.
Как Шези напомнил мне, (лексические) сравнения числовых строк не обязательно дают тот же результат, что и прямые числовые сравнения; Для этого потребуются начальные нули. Так что, в конце концов, сохранение __ version_info __
(или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии.
__ version_info __
(или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии. (лексические) сравнения числовых строк не обязательно дают тот же результат, что и прямые числовые сравнения; Для этого потребуются начальные нули. Так что, в конце концов, сохранение __ version_info __
(или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии. Еще я видел другой стиль:
>>> django.VERSION
(1, 1, 0, 'final', 0)