Estratégia para acompanhar as mudanças na linguagem (Python)

16

Escrever código que ainda funcionará daqui a alguns anos

Linguagens de programação mudam. As bibliotecas mudam. Alguns códigos de 5, 10 ou até 20 anos atrás ainda podem ser executados e produzir os resultados esperados, enquanto alguns códigos de 2 anos podem falhar com um erro de sintaxe. Isso é parcialmente inevitável, pois as línguas evoluem (pelo menos, a maioria delas). Os desenvolvedores têm a responsabilidade de manter seu código. Mas, às vezes, a estabilidade é um requisito importante no código de produção, e o código deve ser executado por 10 anos sem a necessidade de alguém revisar o código todos os anos para adaptá-lo às mudanças de idioma. Ou posso ter pequenos scripts, por exemplo para análise de dados científicos, que preciso revisitar depois de não tocá-los por anos. Por exemplo, nos escritórios de meteorologia, há muito código Fortran operacional, mesmo para peças essenciais que não são de velocidade, e a estabilidade do código é uma das razões. EU' O medo da instabilidade é um dos objetos que eles têm contra a mudança para o Python (além da inércia da linguagem, é claro; é possível apenas para o novo código que não depende do código antigo). Obviamente, uma estratégia para código estável é congelar todo o sistema operacional. Mas isso nem sempre é viável.

Estou usando o Python como no exemplo, mas o problema não se limita ao Python em particular.

Documentos sobre problemas de compatibilidade com o Python

No caso do Python, existem vários documentos que descrevem a política para alterações incompatíveis com versões anteriores.

PEP-5

De acordo com o PEP 5 :

Deve haver pelo menos um período de transição de um ano entre o lançamento da versão de transição do Python e o lançamento da versão incompatível com versões anteriores. Os usuários terão pelo menos um ano para testar seus programas e migrá-los do uso da construção obsoleta para a alternativa.

Pessoalmente, considero que um ano é bastante curto. Isso significa que eu posso escrever um código e daqui a 1 ano e meio não funcionará mais.

PEP 291

O PEP 291 contém uma lista incompleta de diretrizes sobre coisas que devem ser evitadas para manter a compatibilidade com versões anteriores. No entanto, está relacionado apenas ao Python 2.x. Como o Python 2.7 é a versão final da série 2.x e o Python 2.7 é apenas para correção de bugs, esse PEP agora é apenas de interesse histórico.

PEP 387

Há também o PEP 387 em alterações incompatíveis com versões anteriores. O PEP 387 é um esboço e não uma política oficial. Em junho de 2009, isso foi discutido na lista de discussão Python-ideas . Parte da discussão se concentrou em como os desenvolvedores podem escrever código robusto contra alterações de idioma. Um post listou alguns conselhos sobre o que não fazer :

Junto com isso, existem várias regras que você pode deduzir que provavelmente são verdadeiras na maior parte do tempo: não chame coisas que começam com "_", não conserte nada, não use substituição dinâmica de classe em objetos de outras classes que não a sua. , não dependa da profundidade das hierarquias de herança (por exemplo, não ".__bases__[0].__bases__[0]"), verifique se seus testes são executados sem produzir DeprecationWarnings, lembre-se de possíveis conflitos de espaço para nome ao adicionar atributos a classes herdadas de outras bibliotecas. Eu não acho que todas essas coisas estão escritas em um só lugar.

Além disso, houve alguns pontos sobre "campos minados" (novos recursos que provavelmente serão alterados) e "áreas congeladas" (APIs muito vendidas praticamente garantidas para não serem alteradas). Citando Antoine Pitrou :

Eu acho que a "área congelada" deve ser definida positivamente (APIs públicas explícitas e comportamento explicitamente garantido) em vez de negativamente (um "campo minado" explícito). Caso contrário, esqueceremos de colocar algumas coisas importantes no campo minado e seremos picados mais tarde quando precisarmos mudar essas coisas de uma maneira incompatível com versões anteriores.

Não parece haver nenhuma conclusão a partir desta discussão, mas ela chega bem perto do âmago do que estou procurando. O segmento tem quase quatro anos, então talvez a situação tenha mudado ou melhorado. Que tipo de código provavelmente sobreviverá e que tipo de código é mais frágil?

Diretrizes de portabilidade

Além dos documentos descritos acima, cada versão do Python vem com uma diretriz de portabilidade : portabilidade para Python 3.2 , portabilidade para Python 3.3 , etc.

Compatibilidade útil

O PEP 3151 me apresentou o conceito de compatibilidade útil . Em minhas próprias palavras, isso se resume à idéia de que somente se o código for cuidadosamente escrito, os desenvolvedores de linguagem precisam ter cuidado para manter a compatibilidade. Realmente não define compatibilidade útil , mas acho que é semelhante às idéias que citei na discussão do PEP 387 acima.

Do ponto de vista dos programadores

Como programador, sei que o Python mudará no futuro e que as pessoas - principalmente eu - tentarão executar meu código talvez daqui a vários anos em uma versão do Python com uma, duas ou talvez três versões menores. Nem tudo será compatível e, na verdade, é fácil criar um código que falhará (uma vez encontrei o código declarando if sys.version[:3] != '2.3': print 'Wrong version, exiting'). O que estou procurando é um conjunto de diretrizes sobre o que fazer e o que não fazer para aumentar as chances de que meu código ainda funcione inalterado no futuro.

Existem tais diretrizes? Como escrevo código Python que ainda será executado no futuro?

A minha pergunta diz respeito tanto ao núcleo Python, a sua biblioteca padrão, mas também para comumente usado add-on bibliotecas, em particular numpy, scipy, matplotlib.


EDIT : Até agora, duas das respostas estão relacionadas a python2 vs. python3. Não é isso que eu quero dizer. Conheço as ferramentas para migrar do Python2 para o Python3. Minha pergunta está relacionada às mudanças de idioma ainda por vir . Podemos fazer melhor do que uma bola de cristal ao encontrar diretrizes de codificação mais estáveis. Por exemplo:

  • import moduleé mais à prova de futuro do que from module import *, porque o último pode quebrar o código se moduleaumentar uma ou mais novas funções / classes.

  • Usar métodos não documentados pode ser menos à prova de futuro do que usar métodos documentados, pois algo que não está documentado pode ser um sinal de que algo ainda não está estável.

É esse tipo de conselhos práticos de codificação que eu procuro. Como se trata de presente → futuro, podemos nos limitar ao Python3, porque o Python2 não vai mais mudar.

gerrit
fonte

Respostas:

13

Este é um problema não resolvido em nosso campo. Não há como ter certeza de que seu código funcionará indefinidamente. Mesmo que o seu código seja realmente perfeito no sentido de compatibilidade com versões anteriores (e, se for, por favor, venha trabalhar para a minha empresa!;)), Se for executado, usado ou usado por qualquer outro software que receba um bug ou que seja alterado de qualquer forma, seu código pode não funcionar.

Portanto, não posso fornecer uma lista de coisas para fazer isso, se você as seguir, garantirá o sucesso. Mas o que você pode fazer é minimizar o risco de quebras futuras e minimizar seus impactos. Um Pythonist mais experiente seria capaz de lhe dar conselhos mais específicos para o Python, então terei que ser mais geral:

  • escreva testes de unidade. Mesmo para coisas que você sabe que não precisam delas.

  • usando bibliotecas e tecnologias populares / bem projetadas / estáveis, evitando as impopulares (e, portanto, provavelmente em breve não serão suportadas)

  • evite escrever código que explora detalhes de implementação. Código para interfaces, não implementações. Código contra várias implementações da mesma interface. Por exemplo, execute seu código no CPython, Jython e IronPython e veja o que acontece. Isso fornecerá ótimos comentários sobre seu código. Porém, isso pode não ser útil para o Python3 - a última vez que ouvi falar, algumas implementações ainda estavam no Python2.

  • escreva um código simples e claro que seja explícito sobre suas suposições

  • escreva código modular e composível. Se algum código precisar fazer algo perigoso (no sentido de ser preparado para o futuro), separe-o para que, mesmo que precise mudar, o restante do código não o faça.

  • tem uma especificação de alguma forma. Isso é semelhante aos pontos sobre testes de unidade, se você usar testes como uma especificação e interfaces, que também podem ser usadas como especificações. (Quero dizer interface no sentido geral, não no sentido da palavra-chave Java).

Fazer qualquer uma dessas coisas pode / aumentará a quantidade de trabalho que você deve realizar. Eu acho que faz sentido - muitos desses pontos também podem ser feitos sobre como escrever um bom código, o que é bastante difícil (na minha opinião). Às vezes, você pode precisar violar algumas dessas sugestões. Isso é perfeitamente aceitável, mas esteja ciente dos custos.

É ótimo que a equipe do Python esteja pensando sobre isso, e com certeza eles são muito mais talentosos e habilidosos do que eu jamais serei. Ainda assim, eu estimaria que há 100% que o código de alguém em algum lugar deixará de funcionar da maneira que deseja quando o Python for atualizado.


fonte
4

Chama-se Gerenciamento de Configuração. Se o sistema nunca for alterado, não deverá quebrar. Portanto, não mude o sistema. Preocupado com os novos lançamentos do Python? Não atualize. Preocupado com novos drivers de dispositivo? Não atualize. Preocupado com os patches do Windows? ...

Ross Patterson
fonte
0

Para Python 2 -> Python 3, já existe uma biblioteca Python 2to3 instalada (ele vem com o pacote original do Python).

Com base nisso, logo após o lançamento de novas versões, deve haver bibliotecas semelhantes que acompanham cada nova versão. No entanto, como Martijn afirmou, bibliotecas como essas serão lançadas apenas para versões principais (como versão 3.0), mas não para versões secundárias (como 3.2). No entanto, entre 3.0 e 3.2 (ou qualquer outra versão secundária), não deve haver nenhum problema de compatibilidade; portanto, a conversão para a versão 3.0 deve estar correta.

Além disso, sugiro que você olhe para esta pergunta .

Rushy Panchal
fonte
1
Não, o 2to3 apenas ajuda a atualizar o código na grande lacuna de versão; não há bibliotecas (necessárias) para atualizar o código nas versões secundárias.
Martijn Pieters
As versões menores do @MartijnPieters não devem ter problemas de compatibilidade, pois não devem haver alterações excessivamente grandes. Se houver problemas de compatibilidade e grandes alterações, uma versão completamente nova deverá ser lançada.
0

Não tenho muito o que acrescentar, o "programa para 2 e uso 2to3" parece ser um adágio comum na Internet ultimamente. No entanto, há algo que você deve considerar:

Chama-se seis (página pypi) . É uma biblioteca python dedicada a ajudar a escrever código executado tanto em python 2 quanto em python 3. Eu já o vi empregado em vários projetos enquanto vasculhava a rede, mas os nomes me escapam no momento.

Aren
fonte
Não é realmente o que eu estou procurando. Eu editei a pergunta, espero que fique mais claro o que estou procurando agora.
gerrit