Suportando diferentes versões do Python

votos
8

Este assunto foi me incomodar por algum tempo.

Para o meu projeto Python eu queria ser capaz de suportar as versões Python 2.4 para 3.1. Pensei um pouco sobre como fazer isso, e, eventualmente, decidiu ter quatro garfos separadas do código-fonte para quatro versões diferentes de Python: 2.4, 2.5, 2.6 e 3.1.

Eu vim para ver isso como uma decisão ruim, principalmente por causa de aborrecimentos de distribuição do Python, que agora tem que fazer quatro vezes em vez de um.

A questão é, o que fazer?

Meu projeto está no campo de computação científica. Eu tenho a impressão de que ainda há muitas pessoas que dependem de Python 2.4.

Alguém sugeriu que eu apenas escrever todo o meu projeto para 2.4, mas que é inaceitável para mim. Isso significa que eu não poderia usar os gestores de contexto, e isso é algo que não vai desistir de.

Como projetos Python comuns apoiar 2.4? Será que eles evitar o uso de gerentes de contexto?

Além disso, existe alguma escolha, mas com um garfo separado para Python 3.1? Eu sei que existem todos os tipos de hacks para fazer o mesmo executar código no 2.xe 3.x, mas uma das razões que eu gosto Python é porque o código é bonito, e eu não vou tolerar tornando-se feio com hacks de compatibilidade.

Por favor me dê sua opinião.

Publicado 09/12/2009 em 13:11
fonte usuário
Em outras línguas...                            


6 respostas

votos
1

Sim, você precisa escrever para Python 2.4 sintaxe para suportar todas 2,4-2,7 na mesma base de código.

Algumas mudanças no Python 2.6 e 2.7 objetivo de torná-lo um pouco mais fácil de escrever um código compatível com 3.x, mas você tem que perder o suporte para 2.5 e abaixo para fazer isso.

Respondeu 09/12/2009 em 13:32
fonte usuário

votos
0

Se as diferenças entre as versões não são extremas, você pode tentar isolá-los em um pacote separado ou módulo em que você escrever código específico da versão para atuar como uma camada de adaptação.

De uma forma trivial, isso pode ser feito sem o módulo separado em casos simples, como quando uma nova versão do Python faz um pacote que costumava ser externo, como (por exemplo) simplejson padrão. Temos algo semelhante a isto em algum código:

try:
    import simplejson as json
except ImportError:
    import json

Para o material não-trivial, como o que você provavelmente tem, você não iria querer tais coisas espalhadas aleatoriamente em toda a sua base de código, então você deve reunir tudo em um só lugar, quando possível, e que a única parte do seu código fazer que é específico da versão.

Isso não pode funcionar tão bem para coisas em que a sintaxe é diferente, tal como o seu comentário sobre querer usar gerentes de contexto. Claro, você pode colocar o código do gerenciador de contexto em um módulo separado, mas que provavelmente vai complicar os lugares onde você estaria usando. Nesses casos, você pode backport certos aspectos críticos (acho que os gestores de contexto poderia ser simulado um pouco facilmente) para este módulo adaptador.

Definitivamente ter bases de código separados é a pior coisa que poderia fazer, então eu certamente recomendaria a trabalhar longe disso. Pelo menos, não arbitrariamente usar os recursos das versões mais recentes do Python, pois embora possa parecer bom tê-los no código (simplificando um determinado bloco da lógica talvez), o fato de que você tem que duplicar essa lógica pela bifurcação da base de código, mesmo em um único módulo, vai mais do que negar os benefícios.

Nós ficar com versões mais antigas de código legado, aprimorando como novos lançamentos sair para apoiá-los, mas manter o apoio para os mais velhos, às vezes com camadas pequeno adaptador. Em algum momento, um grande lançamento do nosso código aparece no calendário, e considerar se é hora de perder o suporte para um Python mais velha. Quando isso acontece, tentamos ultrapassar várias versões, indo (por exemplo) 2,4-2,6 diretamente, e só então começar a realmente aproveitando a nova sintaxe e características não-adaptáveis.

Respondeu 09/12/2009 em 13:54
fonte usuário

votos
0

Primeiro de chamada que você precisa ter em mente que Python 2.x ações em sua maioria a mesma sintaxe que é compatível com versões anteriores, novas funcionalidades e adições de lado. Há outras coisas a considerar que não são necessariamente erros, como DeprecationWarning mensagens que enquanto não prejudicial, são feios e podem causar confusão.

Python 3.x é backward-incompatíveis por design e tem a intenção de deixar tudo do velho cruft trás. Python 2.6 introduziu muitas mudanças que também estão em 3.x do Python para ajudar a facilitar a transição. Para ver todos eles eu recomendo ler sobre o que há de novo em Python 2.6 documento. Por esta razão, é muito possível escrever código para Python 2.6 que também será executado em Python 3.1, mas isso não é sem suas advertências.

Mesmo ainda há muitas mudanças de sintaxe menores, mesmo entre as versões 2.x que vai exigir que você você envolve um monte de seu código em try/ exceptblocos, por isso, se é isso que você está disposto a fazer, em seguida, ter um 2.xe 3.x filial é totalmente possível. Acho que você vai achar que você vai estar fazendo um monte de atributo e ensaios de tipo em seus objetos para fazer o que você quer fazer.

Eu recomendo que você verifique o código de grandes projetos lá fora, que suportam várias versões do Python. Torcido Matrix é o primeiro que vem à mente. Seu código é um exemplo maravilhoso de como o código Python deve ser escrito.

No final, o que você está definindo a fazer não vai ser fácil, então prepare-se para um monte de trabalho!

Respondeu 09/12/2009 em 13:58
fonte usuário

votos
1

Há parecem ser diferentes respostas para o seu problema.

Primeiro, se você quer oferecer todas as funções para todas as versões do Python, então sim, você provavelmente está preso com usando o menor possível funcionalidade subconjunto - daí a escrever seu código para Python 2.4. Ou você poderia backport características de intérpretes mais recentes se eles estão python puro (que não é o caso dos gestores de contexto ou coroutines nem).

Ou você poderia dividir suporte versão em recursos - se você acha que há um recurso (opcional), que teria grande vantagem de, digamos, os gerentes de contexto, você pode torná-lo disponível em um módulo separado e apenas dizer que 2,4 usuários não têm esse recurso.

A fim de apoiar Python 3 tomar um olhar para o ajudante 2to3, se você escrever seu código corretamente há uma boa chance que você não vai precisar manter duas bases de código separadas.

Respondeu 09/12/2009 em 13:58
fonte usuário

votos
0

Você poderia tentar virtualenv e distribuir seu aplicativo usando uma única versão Python. Isto pode ou não ser prático no seu caso though.

Respondeu 09/12/2009 em 18:28
fonte usuário

votos
0

Temos relacionado problema, um grande sistema que suporta tanto jython e CPython de volta para 2,4. Basicamente, você precisa isolar o código que precisa ser escrito de forma diferente em um esperamos pequeno conjunto de módulos, e ter as coisas são importados condicionalmente.

# module svn.py
import sys
if sys.platform.startswith('java'):
    from jythonsvn import *
else:
    from nativesvn import *

No seu exemplo você usaria testes contra sys.version_info, presumivelmente. Você poderia definir algumas coisas simples em um módulo de serviço público, que você usaria como: de util import *

# module util.py
import sys
if sys.exc_info[0] == 2:
    if sys.exc_info[1] == 4:
        from util_py4 import *
    ...

Então as coisas em util_py4.py como:

def any(seq):                # define workaround functions where possible
    for a in seq:
        if a: return True
    return False
...

Embora este é um problema diferente do que portar (desde que você queira continuar a apoiar), este link dá alguma orientação útil http://python3porting.com/preparing.html (como fazer uma variedade de outros artigos sobre a portagem de python 2.x) .

O seu comentário que você simplesmente não pode viver sem gerentes de contexto é um pouco confuso embora. Enquanto os gerentes de contexto são poderosos e tornar o código mais legível e minimizar o risco de erros, você simplesmente não será capaz de tê-los no código da sua versão 2.4.

### 2.5 (with appropriate future import) and later
with open('foo','rb')as myfile:
   # do something with myfile

### 2.4 and earlier   
myfile = None
try:
    myfile = open('foo','rb')
    # do something with myfile
finally:
    if myfile: myfile.close()

Desde que você quer para apoiar 2.4 você terá um corpo de código que só tem que ter a segunda sintaxe. Será que vai realmente ser mais elegante para escrever as duas coisas?

Respondeu 23/03/2012 em 13:48
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more