Estrategia para mantenerse al día con los cambios de lenguaje (Python)

16

Escribir código que aún se ejecutará dentro de años

Los lenguajes de programación cambian. Las bibliotecas cambian. Algunos códigos de hace 5, 10 o incluso 20 años aún podrían ejecutarse y producir los resultados esperados, mientras que algunos códigos de 2 años podrían fallar con un error de sintaxis. Esto es en parte inevitable, ya que los idiomas evolucionan (al menos, la mayoría lo hacen). Los desarrolladores tienen la responsabilidad de mantener su código. Pero a veces, la estabilidad es un requisito importante en el código de producción, y el código simplemente debe ejecutarse durante 10 años sin la necesidad de que alguien revise el código cada año para adaptarlo a los cambios de idioma. O podría tener pequeños guiones, por ejemplo para el análisis de datos científicos, que necesito revisar después de no tocarlos durante años. Por ejemplo, en las oficinas meteorológicas hay una gran cantidad de código operativo de Fortran incluso para piezas que no son esenciales para la velocidad, y la estabilidad del código es una de las razones. YO' He escuchado que el miedo a la inestabilidad es uno de los objetos que tienen en contra de mudarse a Python (aparte de la inercia del lenguaje, por supuesto; solo es posible para el nuevo código que no depende del código anterior). Por supuesto, una estrategia para un código estable es congelar todo el sistema operativo. Pero eso no siempre es factible.

Estoy usando Python como ejemplo, pero el problema no se limita a Python en particular.

Documentos sobre problemas de compatibilidad con Python

En el caso de Python, hay varios documentos que describen la política para cambios incompatibles con versiones anteriores.

PEP-5

Según la PEP 5 :

Debe haber al menos un período de transición de un año entre el lanzamiento de la versión de transición de Python y el lanzamiento de la versión incompatible con versiones anteriores. Los usuarios tendrán al menos un año para probar sus programas y migrarlos del uso de la construcción obsoleta a la alternativa.

Personalmente, considero que un año es bastante corto. Significa que podría escribir algo de código, y dentro de 1 año y medio ya no funcionará.

PEP 291

PEP 291 contiene una lista incompleta de pautas de cosas que deben evitarse para mantener la compatibilidad con versiones anteriores. Sin embargo, solo se relaciona con Python 2.x. Como Python 2.7 es la versión final de la serie 2.x y Python 2.7 es solo de corrección de errores, este PEP ahora solo es de interés histórico.

PEP 387

También hay PEP 387 sobre cambios incompatibles con versiones anteriores. PEP 387 es un borrador y no una política oficial. En junio de 2009, esto se discutió en la lista de correo de Python-ideas . Parte de la discusión se centró en cómo los desarrolladores pueden escribir código que sea robusto contra los cambios de idioma. Una publicación enumeró algunos consejos sobre qué no hacer :

Junto con esto, hay varias reglas que puede inferir que probablemente sean ciertas la mayor parte del tiempo: no llame a las cosas desde el principio "_", no aplique parches a nada, no use el reemplazo dinámico de clases en objetos de clases que no sean las suyas , no dependa de la profundidad de las jerarquías de herencia (por ejemplo, no ".__bases__[0].__bases__[0]"), asegúrese de que sus pruebas se ejecuten sin producir DeprecationWarnings, tenga en cuenta los posibles conflictos de espacio de nombres al agregar atributos a clases que heredan de otras bibliotecas. Sin embargo, no creo que todas estas cosas estén escritas en un solo lugar.

Además, hubo algunos puntos sobre los "campos de minas" (nuevas características que probablemente cambiarán) y las "áreas congeladas" (API muy vendidas, prácticamente garantizadas para no cambiar). Citando a Antoine Pitrou :

Creo que el "área congelada" debería definirse positivamente (API públicas explícitas y comportamiento garantizado explícitamente) en lugar de negativamente (un "campo de minas" explícito). De lo contrario, olvidaremos poner algunas cosas importantes en el campo de minas y ser mordidos más tarde cuando necesitemos cambiar esas cosas de una manera incompatible con versiones anteriores.

No parece haber ninguna conclusión de este hilo, pero se acerca bastante al núcleo de lo que estoy buscando. El hilo tiene casi cuatro años, por lo que tal vez la situación ha cambiado o mejorado. ¿Qué tipo de código es probable que sobreviva y qué tipo de código es más frágil?

Pautas de portabilidad

Además de los documentos descritos anteriormente, cada versión de Python viene con una guía de portabilidad : portar a Python 3.2 , portar a Python 3.3 , etc.

Compatibilidad útil

PEP 3151 me presentó el concepto de compatibilidad útil . En mis propias palabras, esto se reduce a la idea de que solo si el código está cuidadosamente escrito, los desarrolladores deben tener cuidado para mantener la compatibilidad. Realmente no define una compatibilidad útil , pero creo que es similar a las ideas que cité de la discusión PEP 387 anterior.

Desde el punto de vista de los programadores.

Como programador, sé que Python cambiará en el futuro y que las personas, especialmente yo, tratarán de ejecutar mi código quizás dentro de varios años en una versión de Python que sea una, dos o quizás tres versiones menores. No todo será compatible y, de hecho, es fácil encontrar un código que fallará (una vez me encontré con el código que indica if sys.version[:3] != '2.3': print 'Wrong version, exiting'). Lo que estoy buscando es un conjunto de pautas sobre qué hacer y qué no hacer para mejorar las posibilidades de que mi código aún se ejecute sin modificaciones en el futuro.

¿Hay alguna de estas pautas? ¿Cómo escribo el código Python que aún se ejecutará en el futuro?

Mi pregunta se refiere tanto al núcleo de Python, a su biblioteca estándar, sino también para uso común complemento de las bibliotecas, en particular numpy, scipy, matplotlib.


EDITAR : Hasta ahora, dos de las respuestas se relacionan con python2 frente a python3. Esto no es lo que quiero decir. Sé sobre herramientas para migrar de Python2 a Python3. Mi pregunta se refiere a cambios de idioma por venir . Podemos hacerlo mejor que una bola de cristal para encontrar pautas de codificación que sean más estables. Por ejemplo:

  • import moduleestá más preparado para el futuro que from module import *, porque este último puede romper el código si modulecrece una o más funciones / clases nuevas.

  • El uso de métodos indocumentados puede ser menos a prueba de futuro que el uso de métodos documentados, ya que algo no documentado puede ser un signo de que algo no es estable todavía.

Es este tipo de consejos prácticos de codificación lo que busco. Como se trata de presente → futuro, podemos limitarnos a Python3, porque Python2 ya no va a cambiar.

gerrit
fuente

Respuestas:

13

Este es un problema sin resolver en nuestro campo. No hay forma de estar seguro de que su código funcionará indefinidamente. Incluso si su código era realmente perfecto en el sentido de compatibilidad directa (y si lo es, ¡venga a trabajar para mi empresa!;)), Si se ejecuta, utiliza o es utilizado por cualquier otro software que tenga un error o cambie de alguna manera, su código puede no funcionar.

Por lo tanto, no puedo darle una lista de cosas para hacer que, si las sigue, garantizará el éxito. Pero lo que puede hacer es minimizar el riesgo de roturas futuras y minimizar sus impactos. Un Pythonist con más conocimientos podría darle consejos más específicos de Python, por lo que tendré que ser más general:

  • escribir pruebas unitarias. Incluso para cosas que sabes no las necesitas.

  • utilizando bibliotecas y tecnologías populares / bien diseñadas / estables, evitando las impopulares (y, por lo tanto, es probable que pronto no sean compatibles)

  • evite escribir código que explote los detalles de implementación. Código para interfaces, no implementaciones. Código contra múltiples implementaciones de la misma interfaz. Por ejemplo, ejecute su código en CPython, Jython y IronPython y vea qué sucede. Esto le dará algunos comentarios excelentes sobre su código. Sin embargo, esto podría no ser útil para Python3: lo último que escuché fue que algunas implementaciones todavía estaban en Python2.

  • escribir código simple y claro que sea explícito sobre sus supuestos

  • escribir código modular y composable. Si algún código debe hacer algo peligroso (en el sentido de futuro), sepárelo para que, incluso si tiene que cambiar, el resto del código no lo haga.

  • tener una especificación de alguna forma. Esto es similar a los puntos sobre las pruebas unitarias, si usa las pruebas como una especificación, y las interfaces, que también pueden usarse como especificaciones. (Me refiero a la interfaz en el sentido general, no al sentido de la palabra clave Java).

Hacer cualquiera de estas cosas puede / aumentará la cantidad de trabajo que tiene que hacer. Creo que eso tiene sentido: muchos de estos puntos también se pueden hacer sobre cómo escribir un buen código, lo cual es bastante difícil (en mi opinión). A veces es posible que deba violar algunas de estas sugerencias. Eso es perfectamente aceptable, pero tenga en cuenta los costos.

Es genial que el equipo de Python esté pensando en esto, y seguro que son mucho más talentosos y hábiles que nunca. Aún así, estimaría que hay un 100% de que el código de alguien en algún lugar dejará de funcionar de la manera deseada cuando se actualice Python.


fuente
4

Se llama Gestión de la configuración. Si el sistema nunca cambia, no debería romperse. Así que no cambies el sistema. ¿Preocupado por los nuevos lanzamientos de Python? No actualices. ¿Preocupado por los nuevos controladores de dispositivo? No actualices. ¿Preocupado por los parches de Windows? ...

Ross Patterson
fuente
0

Para Python 2 -> Python 3, ya hay una biblioteca Python 2to3 instalada (viene con el paquete original de Python).

Basado en eso, poco después de que se lancen nuevas versiones, debería haber bibliotecas similares que vienen con cada nueva versión. Sin embargo, como Martijn declaró, las bibliotecas como estas solo se lanzarán para versiones principales (como la versión 3.0) pero no para versiones menores (como 3.2). Sin embargo, entre 3.0 y 3.2 (o cualquier otra versión menor), no debería haber problemas de compatibilidad, por lo que la conversión a la versión 3.0 debería estar bien.

Además, le sugiero que mire esta pregunta .

Rushy Panchal
fuente
1
No, 2to3 solo lo ayuda a actualizar el código en la brecha de versión principal; no hay bibliotecas (necesarias) para actualizar el código en versiones menores.
Martijn Pieters
@MartijnPieters Las versiones menores no deberían tener problemas de compatibilidad, ya que no debería haber cambios excesivamente grandes. Si hay problemas de compatibilidad y grandes cambios, se debe lanzar una versión completamente nueva.
0

No tengo mucho que agregar, el "programa para 2 y uso 2to3" parece ser un tema común en Internet últimamente. Sin embargo, hay algo que debes mirar:

Se llama seis (página de pypi) . Es una biblioteca de Python dedicada a ayudar a escribir código que se ejecuta tanto en Python 2 como en Python 3. Lo he visto empleado en varios proyectos mientras examinaba la red, pero los nombres se me escapan en este momento.

Aren
fuente
No es realmente lo que busco. He editado la pregunta, espero que quede más claro lo que estoy buscando ahora.
gerrit