O tópico atual é sobre a verificação da versão python de um programa / script python. Caso você esteja procurando verificar a versão do interpretador python instalado em sua máquina a partir da linha de comando, consulte o seguinte post - Qual versão do Python eu tenho instalada?
RBT
1
aqui é uma maneira divertida de python separado 3 e 2 ...python_version = int(str(range(3))[-2])
Chris_Rands
@RBT: para uma verificação em uma linha na linha de comando, veja minha resposta .
smci
Respostas:
1378
Esta informação está disponível na cadeia sys.version no módulo sys :
>>>import sys
Legível por humanos:
>>>print(sys.version)# parentheses necessary in python 3. 2.5.2(r252:60911,Jul312008,17:28:52)[GCC 4.2.3(Ubuntu4.2.3-2ubuntu7)]
Para garantir que um script seja executado com um requisito de versão mínima do interpretador Python, adicione-o ao seu código:
assert sys.version_info >=(2,5)
Isso compara as informações das versões principais e secundárias. Adicionar micro (= 0, 1, etc) e até mesmo releaselevel (= 'alpha', 'final', etc) para a tupla como você gosta. Observe, no entanto, que quase sempre é melhor "pular" para verificar se um determinado recurso está presente e, se não estiver, uma solução alternativa (ou resgate). Às vezes, os recursos desaparecem em versões mais recentes, sendo substituídos por outros.
Você também pode acessar alguns dos campos sys.version_infocomo propriedades, por isso PY3 = sys.version_info.major == 3pode ser um pouco mais atraente.
@gcb seu snippet de código será interrompido sempre que o Python 4 acontecer. Você deveria fazer if sys.version_info >= (3,). É totalmente pitônico comparar tuplas de tamanhos diferentes e ele fará a coisa certa.
Isso é uma característica versão bacana eu não tinha visto, e um pouco mais fácil de usar (pelo menos para mim) do que a versão regular ...
Wayne Werner
6
@sorin: você pode explicar como isso é melhor do que, por exemplo, a resposta de Seth? Já que você afirma que isso é o melhor, estou me perguntando.
0xC0000022L
3
@ 0xC0000022L Você já se perguntou como seria capaz de comparar o texto da tupla? Como 'final' se compara a beta, rc ou o que quer que esteja lá. Em vez disso, se você tiver um valor numérico, sempre poderá especificar uma versão exata.
Sorin
1
@sorin: uhm, isso não importa exatamente, importa? Se eu comparar com (2,6,4)o 'final'não parece afetar a comparação e não deveria. Aparentemente, não é necessário fatiar quando comparo as partes "mais significativas" da tupla. Parece que é assim que é tratado e é disso que se trata minha pergunta. Não estou dizendo que esta solução não tem seu mérito, estou apenas me perguntando por que é a melhor - ou seja, o que estou perdendo.
0xC0000022L
11
O nível de liberação é definido como um de 'alfa', 'beta', 'candidato' ou 'final', que também é comparado corretamente ...
Fredrik
65
Sua melhor aposta é provavelmente algo assim:
>>>import sys
>>> sys.version_info
(2,6,4,'final',0)>>>ifnot sys.version_info[:2]==(2,6):...print"Error, I need python 2.6"...else:...from my_module import twoPointSixCode
>>>
Além disso, você sempre pode agrupar suas importações em uma tentativa simples, que deve detectar erros de sintaxe. E, ao ponto de @ Heikki, esse código será compatível com versões muito mais antigas do python:
>>>try:...from my_module import twoPointSixCode
...exceptException:...print"can't import, probably because your python is too old!">>>
Por que uma exceção simples e não um ImportError? : P
mortal
4
@deadly - O ImportError não captura SyntaxErrors, que serão lançados se você tentar usar uma nova sintaxe em um python antigo, como tentar usar o atalho condicional na versão anterior à 2.5.
Seth
except Exceptioné muito amplo. Não seria melhor usar exceções específicas que você espera?
Paradox Fermi 01/02
1
@Fermiparadox - Ser amplo mantém as suposições baixas. A except Exception:linha por si só já assume um python moderno (2.x +). Talvez algum python futuro reorganize nomes de exceção de alguma maneira incompatível com versões anteriores? (? Provavelmente não, mas quem sabe o que python será parecido em 20 anos, quando todos nós temos implantes rift globo ocular Oculus Código dura muito tempo.)
Para a função de impressão, seria melhor entre parênteses, pensando em compatibilidade. Se alguém usar amostra na versão 3, o erro de sintaxe estará lá aguardando.
Alex Chiang
47
Coloque algo como:
#!/usr/bin/env/pythonimport sys
if sys.version_info<(2,6,0):
sys.stderr.write("You need python 2.6 or later to run this script\n")
exit(1)
no topo do seu script.
Observe que, dependendo do que mais há no seu script, as versões mais antigas do python que o destino podem não conseguir carregar o script, portanto, não será suficiente o suficiente para relatar esse erro. Como solução alternativa, você pode executar o procedimento acima em um script que importa o script com o código mais moderno.
Isso está incorreto (ou pelo menos incompleto) porque os intérpretes antigos vomitarão em construções de linguagem mais recentes, como x if Pred() else y. Eles morrerão durante a fase "lexing" e nunca terão a chance de realmente executarexit(1) . A resposta de Seth está correta ao encapsular os novos recursos de idioma em outros arquivos.
Mark Rushakoff
2
@ MarkRushakoff: seu comentário é confuso. Qual aspecto desta resposta está errado? O elseramo ausente ou para o qual a <é usado version_info? O AFAIK Python preenche os valores ausentes nas tuplas, e tudo isso deve ser válido antes da versão 2.6, não? Portanto, a resposta de Seth usa fatias (de forma redundante), enquanto essa não é, e isso deixa seu comentário ainda mais confuso.
0xC0000022L
5
Acho que o que MarkRushakoff está dizendo é que, se você tiver isso na parte superior de um arquivo, e um novo recurso de idioma em outro lugar no mesmo arquivo, a versão antiga do python morrerá ao carregar o arquivo, antes de executá-lo, para que o erro não seja mostrado. Basicamente, você deve colocar a verificação acima (ou outra verificação) na parte superior de um arquivo e importar o código que requer uma nova versão do python a partir de arquivos separados.
Rjmunro
1
Yep, o que @rjmunro disse :)
Mark Rushakoff
25
Aqui está uma versão curta da linha de comando que sai imediatamente (útil para scripts e execução automatizada):
@vigilancer você está certo, na hora de escrever não era tão relevante ainda, mas eu tenho atualizado para Python 3 agora :)
Wolph
Bom, isso resolve meu problema em que eu estava obtendo o número da versão capturando a saída python2 --versione python3 --versiondo PHP. Enquanto gostaria de obter este sem problemas via passthru(), o ex-só imprimir para a tela, mas nunca ser capturado, mesmo quando redirecionado para um arquivo ...
Tox
1
@tox Você pode dizer print() para gravar em um arquivo, se for mais conveniente.
Wolph 5/09/19
No meu caso, isso seria mais do que já estou redirecionando a passthru()saída para um arquivo. Sua solução faz exatamente o que eu preciso. :)
Tox
14
Com o sixmódulo, você pode fazer isso:
import six
if six.PY2:# this is python2.xelse:# six.PY3# this is python3.x
"A maneira mais simples" ... de fazer algo diferente do que foi solicitado.
Luc
4
Como Seth disse, o script principal pode verificar sys.version_info(mas observe que isso não apareceu até a versão 2.0, portanto, se você quiser suportar versões mais antigas, precisará verificar outra propriedade de versão do módulo sys).
Mas você ainda precisa cuidar de não usar nenhum recurso da linguagem Python no arquivo que não esteja disponível nas versões mais antigas do Python. Por exemplo, isso é permitido no Python 2.5 e posterior:
try:passexcept:passfinally:pass
mas não funcionará em versões mais antigas do Python, porque você só pode ter, exceto OU finalmente, a tentativa. Portanto, para compatibilidade com versões mais antigas do Python, você precisa escrever:
Várias respostas já sugerem como consultar a versão atual do python. Para verificar programaticamente os requisitos de versão, eu usaria um dos dois métodos a seguir:
# Method 1: (see krawyoti's answer)import sys
assert(sys.version_info >=(2,6))# Method 2: import platform
from distutils.version importStrictVersionassert(StrictVersion(platform.python_version())>="2.6")
Apenas por diversão, a seguir é uma maneira de fazê-lo no CPython 1.0-3.7b2, Pypy, Jython e Micropython. Isso é mais uma curiosidade do que uma maneira de fazê-lo no código moderno. Eu o escrevi como parte de http://stromberg.dnsalias.org/~strombrg/pythons/ , que é um script para testar um trecho de código em várias versões de python de uma só vez, para que você possa entender facilmente o que python recursos são compatíveis com quais versões do python:
via_platform =0
check_sys =0
via_sys_version_info =0
via_sys_version =0
test_sys =0try:import platform
except(ImportError,NameError):# We have no platform module - try to get the info via the sys module
check_sys =1ifnot check_sys:if hasattr(platform,"python_version"):
via_platform =1else:
check_sys =1if check_sys:try:import sys
test_sys =1except(ImportError,NameError):# just let via_sys_version_info and via_sys_version remain False - we have no sys modulepassif test_sys:if hasattr(sys,"version_info"):
via_sys_version_info =1elif hasattr(sys,"version"):
via_sys_version =1else:# just let via_sys remain Falsepassif via_platform:# This gives pretty good info, but is not available in older interpreters. Also, micropython has a# platform module that does not really contain anything.print(platform.python_version())elif via_sys_version_info:# This is compatible with some older interpreters, but does not give quite as much info.print("%s.%s.%s"% sys.version_info[:3])elif via_sys_version:import string
# This is compatible with some older interpreters, but does not give quite as much info.
verbose_version = sys.version
version_list = string.split(verbose_version)print(version_list[0])else:print("unknown")
sys.version_infoparece não retornar um a tuplepartir de 3,7. Em vez disso, ele retorna uma classe especial, para que todos os exemplos usando tuplas não funcionem, pelo menos para mim. Aqui está a saída de um console python:
É algo como uma subclasse de namedtuplee compará-lo com a tupla definitivamente funciona. Para obter igualdade total, você precisa de um tipo de cinco elementos: maior, menor, micro, nível de liberação (string) e serial.
Mikhail Edoshin 28/03/19
0
A maneira ainda mais simples e simples:
No Spyder, inicie um novo "IPython Console" e execute qualquer um dos scripts existentes.
Agora a versão pode ser vista na primeira saída impressa na janela do console:
"Python 3.7.3 (padrão, 24 de abril de 2019 às 15:29:51) ..."
Nota: em .format()vez de f-strings ou '.'.join()permite que você use caracteres arbitrários de formatação e separador, por exemplo, para tornar uma string de uma palavra aceitável. Coloquei isso dentro de um script do utilitário bash que relata todas as versões importantes: python, numpy, pandas, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc / g ++ etc. Útil para registro, replicabilidade, solução de problemas, relatórios de erros etc. .
python_version = int(str(range(3))[-2])
Respostas:
Esta informação está disponível na cadeia sys.version no módulo sys :
Legível por humanos:
Para processamento adicional:
Para garantir que um script seja executado com um requisito de versão mínima do interpretador Python, adicione-o ao seu código:
Isso compara as informações das versões principais e secundárias. Adicionar micro (=
0
,1
, etc) e até mesmo releaselevel (='alpha'
,'final'
, etc) para a tupla como você gosta. Observe, no entanto, que quase sempre é melhor "pular" para verificar se um determinado recurso está presente e, se não estiver, uma solução alternativa (ou resgate). Às vezes, os recursos desaparecem em versões mais recentes, sendo substituídos por outros.fonte
PY3 = sys.version_info[0] == 3
sys.version_info
como propriedades, por issoPY3 = sys.version_info.major == 3
pode ser um pouco mais atraente.if sys.version_info >= (3,)
. É totalmente pitônico comparar tuplas de tamanhos diferentes e ele fará a coisa certa.Na linha de comando (observe o capital 'V'):
Isso está documentado no 'man python'.
fonte
Eu gosto
sys.hexversion
de coisas assim.http://docs.python.org/library/sys.html#sys.hexversion
fonte
(2,6,4)
o'final'
não parece afetar a comparação e não deveria. Aparentemente, não é necessário fatiar quando comparo as partes "mais significativas" da tupla. Parece que é assim que é tratado e é disso que se trata minha pergunta. Não estou dizendo que esta solução não tem seu mérito, estou apenas me perguntando por que é a melhor - ou seja, o que estou perdendo.Sua melhor aposta é provavelmente algo assim:
Além disso, você sempre pode agrupar suas importações em uma tentativa simples, que deve detectar erros de sintaxe. E, ao ponto de @ Heikki, esse código será compatível com versões muito mais antigas do python:
fonte
except Exception
é muito amplo. Não seria melhor usar exceções específicas que você espera?except Exception:
linha por si só já assume um python moderno (2.x +). Talvez algum python futuro reorganize nomes de exceção de alguma maneira incompatível com versões anteriores? (? Provavelmente não, mas quem sabe o que python será parecido em 20 anos, quando todos nós temos implantes rift globo ocular Oculus Código dura muito tempo.)Use
platform
épython_version
do stdlib:fonte
Coloque algo como:
no topo do seu script.
Observe que, dependendo do que mais há no seu script, as versões mais antigas do python que o destino podem não conseguir carregar o script, portanto, não será suficiente o suficiente para relatar esse erro. Como solução alternativa, você pode executar o procedimento acima em um script que importa o script com o código mais moderno.
fonte
x if Pred() else y
. Eles morrerão durante a fase "lexing" e nunca terão a chance de realmente executarexit(1)
. A resposta de Seth está correta ao encapsular os novos recursos de idioma em outros arquivos.else
ramo ausente ou para o qual a<
é usadoversion_info
? O AFAIK Python preenche os valores ausentes nas tuplas, e tudo isso deve ser válido antes da versão 2.6, não? Portanto, a resposta de Seth usa fatias (de forma redundante), enquanto essa não é, e isso deixa seu comentário ainda mais confuso.Aqui está uma versão curta da linha de comando que sai imediatamente (útil para scripts e execução automatizada):
Ou apenas os principais, menores e micro:
fonte
python2 --version
epython3 --version
do PHP. Enquanto gostaria de obter este sem problemas viapassthru()
, o ex-só imprimir para a tela, mas nunca ser capturado, mesmo quando redirecionado para um arquivo ...print()
para gravar em um arquivo, se for mais conveniente.passthru()
saída para um arquivo. Sua solução faz exatamente o que eu preciso. :)Com o
six
módulo, você pode fazer isso:fonte
sys.version oferece o que você deseja, basta escolher o primeiro número :)
fonte
A maneira mais simples
Basta digitar python no seu terminal e você pode ver a versão como se segue
fonte
Como Seth disse, o script principal pode verificar
sys.version_info
(mas observe que isso não apareceu até a versão 2.0, portanto, se você quiser suportar versões mais antigas, precisará verificar outra propriedade de versão do módulo sys).Mas você ainda precisa cuidar de não usar nenhum recurso da linguagem Python no arquivo que não esteja disponível nas versões mais antigas do Python. Por exemplo, isso é permitido no Python 2.5 e posterior:
mas não funcionará em versões mais antigas do Python, porque você só pode ter, exceto OU finalmente, a tentativa. Portanto, para compatibilidade com versões mais antigas do Python, você precisa escrever:
fonte
Várias respostas já sugerem como consultar a versão atual do python. Para verificar programaticamente os requisitos de versão, eu usaria um dos dois métodos a seguir:
fonte
Apenas por diversão, a seguir é uma maneira de fazê-lo no CPython 1.0-3.7b2, Pypy, Jython e Micropython. Isso é mais uma curiosidade do que uma maneira de fazê-lo no código moderno. Eu o escrevi como parte de http://stromberg.dnsalias.org/~strombrg/pythons/ , que é um script para testar um trecho de código em várias versões de python de uma só vez, para que você possa entender facilmente o que python recursos são compatíveis com quais versões do python:
fonte
Verifique a versão do Python:
python -V
oupython --version
ouapt-cache policy python
você também pode executar
whereis python
para ver quantas versões estão instaladas.fonte
Se você deseja detectar o pré-Python 3 e não deseja importar nada ...
... você pode (ab) usar alterações no escopo da compreensão da lista e fazê-lo em uma única expressão :
fonte
Para verificar a versão do Python para comandos no Windows, execute os seguintes comandos em um prompt de comando e verifique a saída
Além disso, para ver a configuração da pasta para cada versão do Python, execute os seguintes comandos:
fonte
resultado
fonte
print("sys.version: {}".format(version))
.sys.version_info
parece não retornar um atuple
partir de 3,7. Em vez disso, ele retorna uma classe especial, para que todos os exemplos usando tuplas não funcionem, pelo menos para mim. Aqui está a saída de um console python:Eu descobri que usar uma combinação de
sys.version_info.major
esys.version_info.minor
parece suficiente. Por exemplo,...verifica se você está executando o Python 3. Você pode até verificar versões mais específicas com ...
pode verificar se você está executando pelo menos o Python 3.5.
fonte
namedtuple
e compará-lo com a tupla definitivamente funciona. Para obter igualdade total, você precisa de um tipo de cinco elementos: maior, menor, micro, nível de liberação (string) e serial.A maneira ainda mais simples e simples:
No Spyder, inicie um novo "IPython Console" e execute qualquer um dos scripts existentes.
Agora a versão pode ser vista na primeira saída impressa na janela do console:
"Python 3.7.3 (padrão, 24 de abril de 2019 às 15:29:51) ..."
fonte
Para verificar na linha de comando, em um único comando, mas inclua as versões principal, secundária, micro, nível de liberação e serial :
Nota: em
.format()
vez de f-strings ou'.'.join()
permite que você use caracteres arbitrários de formatação e separador, por exemplo, para tornar uma string de uma palavra aceitável. Coloquei isso dentro de um script do utilitário bash que relata todas as versões importantes: python, numpy, pandas, sklearn, MacOS, xcode, clang, brew, conda, anaconda, gcc / g ++ etc. Útil para registro, replicabilidade, solução de problemas, relatórios de erros etc. .fonte
Se você estiver trabalhando no linux, apenas dê a
python
saída do comando , será assimfonte
Python
versão do script, também resposta semelhante já publicada anteriormente: stackoverflow.com/a/35294211/950762