Pregunta

Me interesaría aprender sobre el desarrollo a gran escala en Python y, especialmente, ¿cómo mantener una base de código grande?

  • Cuando realiza cambios de incompatibilidad en la firma de un método, ¿cómo encuentra todos los lugares donde se llama a ese método? En C ++ / Java, el compilador lo encontrará por usted, ¿cómo lo hace en Python?

  • Cuando realiza cambios en el interior del código, ¿cómo descubre qué operaciones proporciona una instancia, ya que no tiene un tipo estático para buscar?

  • ¿Cómo maneja / previene los errores de escritura (errores tipográficos)?

  • ¿Se utilizan UnitTest como sustituto de la verificación de tipo estático?

Como puedes adivinar, casi solo trabajé con lenguajes estáticamente escritos (C ++ / Java), pero me gustaría probar Python para programas más grandes. Pero tuve una experiencia muy mala, hace mucho tiempo, con el lenguaje clipper (dBase), que también se escribió dinámicamente.

¿Fue útil?

Solución

Dado que nadie señaló pychecker, pylint y herramientas similares, lo haré: pychecker y pylint son herramientas que pueden ayudarlo a encontrar suposiciones incorrectas (sobre firmas de funciones, atributos de objetos, etc.) No encontrarán todo lo que un compilador podría encontrar. encontrar en un idioma estáticamente escrito, pero también pueden encontrar problemas que tales compiladores para dichos idiomas no pueden encontrar también.

Python (y cualquier lenguaje de tipo dinámico) es fundamentalmente diferente en términos de los errores que es probable que cause y cómo los detectaría y solucionaría. Tiene ventajas y desventajas definidas, pero muchos (incluyéndome a mí) dirían que en el caso de Python, la facilidad de escribir código (y la facilidad de hacerlo estructuralmente sólido) y de modificar el código sin romper La compatibilidad API (agregando nuevos argumentos opcionales, proporcionando diferentes objetos que tienen el mismo conjunto de métodos y atributos) lo hace adecuado para bases de código grandes.

Otros consejos

No use un destornillador como martillo

Python no es un lenguaje de tipo estático, así que no intentes usarlo de esa manera.

Cuando usa una herramienta específica, la usa para lo que se ha construido. Para Python, significa:

  • Pato escribiendo : sin verificación de tipo. Solo el comportamiento importa. Por lo tanto, su código debe estar diseñado para usar esta función. Un buen diseño significa firmas genéricas, sin dependencias entre componentes, altos niveles de abstracción. Entonces, si cambia algo, no tendrá que cambiar el resto del código. Python tampoco se quejará, para lo que ha sido construido. Los tipos no son un problema.

  • Biblioteca estándar enorme . No necesita cambiar todas sus llamadas en el programa si usa funciones estándar que no ha codificado usted mismo. Y Python viene con baterías incluidas. Sigo descubriéndolos todos los días. No tenía idea de la cantidad de módulos que podía usar cuando comencé e intenté reescribir cosas existentes como todos. Está bien, no puedes hacerlo bien desde el principio.

No escribes Java, C ++, Python, PHP, Erlang, lo que sea, de la misma manera. Son buenas razones por las que hay espacio para cada uno de tantos idiomas diferentes, no hacen lo mismo.

Las pruebas unitarias no son un sustituto

Las pruebas unitarias deben realizarse con cualquier idioma. ¡La biblioteca de pruebas unitarias más famosa ( JUnit ) es del mundo Java!

Esto no tiene nada que ver con los tipos. Verificas comportamientos, de nuevo. Evitas problemas con la regresión. Asegura a su cliente que está en camino.

Python para proyectos a gran escala

  

Idiomas, bibliotecas y marcos   no escalar Las arquitecturas sí.

Si diseña una arquitectura sólida, si puede hacer que evolucione rápidamente, entonces escalará. Ayuda de pruebas unitarias, verificación automática de código también. Pero son solo redes de seguridad. Y los pequeños.

Python es especialmente adecuado para grandes proyectos porque impone algunas buenas prácticas y tiene muchos patrones de diseño habituales incorporados. Pero, de nuevo, no lo use para lo que no está diseñado. Por ejemplo: Python no es una tecnología para tareas intensivas de CPU.

En un gran proyecto, lo más probable es que use varias tecnologías diferentes de todos modos. Como SGBD (francés para DBMS ) y un lenguaje de plantillas, o bien. Python no es una excepción.

Probablemente quiera usar C / C ++ para la parte de su código que necesita para ser rápido. O Java para encajar en un entorno Tomcat . No se, no me importa. Python puede jugar bien con estos.

Como conclusión

Mi respuesta puede parecer un poco grosera, pero no me malinterpreten: esta es una muy buena pregunta.

Mucha gente viene a Python con viejos hábitos. Me jodí tratando de codificar Java como Python. Puedes, pero nunca obtendrás lo mejor.

Si has jugado / quieres jugar con Python, ¡es genial! Es una herramienta maravillosa. Pero solo una herramienta, realmente.

Tenía algo de experiencia con la modificación de "Frets On Fire", un python de código abierto "Guitar Hero". clon.

tal como lo veo, python no es realmente adecuado para un proyecto a gran escala.

Me encontré pasando una gran parte del tiempo de desarrollo depurando problemas relacionados con la asignación de tipos incompatibles, cosas que los lenguajes de tipo estático revelarán sin esfuerzo en tiempo de compilación. Además, dado que los tipos se determinan en tiempo de ejecución, tratar de entender el código existente se vuelve más difícil, porque no tienes idea de cuál es el tipo de ese parámetro que estás viendo actualmente.

además de eso, las funciones de llamada que usan su cadena de nombre con la función incorporada __getattr__ generalmente son más comunes en Python que en otros lenguajes de programación, lo que hace que el gráfico de llamada a una determinada función sea algo difícil (aunque también puede llamar a funciones con su nombre en algunos idiomas escritos estáticamente).

Creo que Python realmente brilla en software a pequeña escala, desarrollo rápido de prototipos y pegado de programas existentes, pero no lo usaría para proyectos de software a gran escala, ya que en ese tipo de programas la mantenibilidad se convierte en el verdadero problema, y ??en mi opinión python es relativamente débil allí.

mi 0,10 EUR:

Tengo varias aplicaciones de Python en estado de 'producción'. nuestra empresa usa java, c ++ y python. desarrollamos con el eclipse ide (pydev para python)

las pruebas unitarias son la solución clave para el problema. (también para c ++ y java)

el mundo menos seguro de "tipado dinámico" te hará menos descuidado con la calidad de tu código

POR EL MODO :

¡el desarrollo a gran escala no significa que use un solo idioma!

el desarrollo a gran escala a menudo utiliza un puñado de idiomas específicos para el problema .

así que acepto el problema del martillo :-)


PS: static-typing & amp; python

Aquí hay algunos elementos que me han ayudado a mantener un sistema bastante grande en Python.

  • Estructura tu código en capas. es decir, lógica de biz separada, lógica de presentación y sus capas de persistencia. Invierta un poco de tiempo en definir estas capas y asegúrese de que todos los miembros del proyecto participen. Para sistemas grandes, crear un marco que lo obligue a una determinada forma de desarrollo también puede ser clave.

  • Las pruebas son clave, sin pruebas unitarias es probable que termines con una base de código inmanejable varias veces más rápido que con otros idiomas. Tenga en cuenta que las pruebas unitarias a menudo no son suficientes, asegúrese de tener varias pruebas de integración / aceptación que pueda ejecutar rápidamente después de cualquier cambio importante.

  • Use el principio Fail Fast . Agregue aserciones para casos en los que sienta que su código puede ser vulnerable.

  • Tenga un registro estándar / manejo de errores que lo ayudará a navegar rápidamente al problema

  • Utilice un IDE (pyDev funciona para mí) que proporciona la integración de escritura anticipada, pyLint / Checker para ayudarlo a detectar errores tipográficos comunes de inmediato y promover algunos estándares de codificación

  • Cuidado con sus importaciones, nunca lo haga desde x import * o haga importaciones relativas sin el uso de.

  • Realice una refactorización, una herramienta de búsqueda / reemplazo con expresiones regulares es a menudo todo lo que necesita para mover métodos / refactorización de tipo de clase.

Cambios incompatibles en la firma de un método. Esto no sucede tanto en Python como en Java y C ++.

Python tiene argumentos opcionales, valores predeterminados y mucha más flexibilidad para definir firmas de métodos. Además, la escritura de pato significa que, por ejemplo, no tiene que cambiar de una clase a una interfaz como parte de un cambio significativo de software. Las cosas simplemente no son tan complejas.

¿Cómo encuentra todos los lugares donde se llama ese método? grep funciona para lenguajes dinámicos. Si necesita conocer cada lugar donde se utiliza un método, grep (o una búsqueda equivalente compatible con IDE) funciona muy bien.

¿Cómo saber qué operaciones proporciona una instancia, ya que no tiene un tipo estático para buscar?

a. Mira la fuente. No tiene que lidiar con el problema de Java / C ++ de las bibliotecas de objetos y los archivos jar. No necesita todas las ayudas y herramientas elaboradas que requieren esos idiomas.

b. Un IDE puede proporcionar información de firma en muchas circunstancias comunes. Puede, fácilmente, derrotar los poderes de razonamiento de su IDE. Cuando eso suceda, probablemente debería revisar lo que está haciendo para asegurarse de que tenga sentido. Si su IDE no puede razonar su información de tipo, tal vez sea demasiado dinámica.

c. En Python, a menudo trabajas a través del intérprete interactivo. A diferencia de Java y C ++, puede explorar sus instancias directamente e interactivamente. No necesita un IDE sofisticado.

Ejemplo:

  >>> x= SomeClass()
  >>> dir(x)

¿Cómo maneja / previene errores de escritura? Igual que los idiomas estáticos: no los evita. Los encuentras y los corriges. Java solo puede encontrar una cierta clase de errores tipográficos. Si tiene dos nombres de clase o variable similares, puede terminar en serios problemas, incluso con la verificación de tipo estático.

Ejemplo:

class MyClass { }
class MyClassx extends MyClass { }

Un error tipográfico con estos dos nombres de clase puede causar estragos. [" Pero no me pondría en esa posición con Java " la gente dice Convenido. Tampoco me pondría en esa posición con Python; haces clases que son profundamente diferentes y fallarán temprano si se usan mal.]

¿Se utilizan UnitTest como sustituto de la verificación de tipo estático? Aquí está el otro punto de vista: la verificación de tipo estático es un sustituto del diseño claro y simple.

He trabajado con programadores que no estaban seguros de por qué funcionaba una aplicación. No podían entender por qué las cosas no se compilaron; El no sabía la diferencia entre la superclase abstracta y la interfaz, y no podía entender por qué un cambio en el lugar hace que otros módulos en un archivo JAR se bloqueen por separado. La verificación de tipo estático les dio una falsa confianza en un diseño defectuoso.

Los lenguajes dinámicos permiten que los programas sean simples. La simplicidad es un sustituto de la verificación de tipo estático. La claridad es un sustituto de la verificación de tipo estático.

Mi regla general es usar lenguajes dinámicos para pequeños proyectos que no son críticos para la misión y lenguajes de tipo estático para grandes proyectos. Encuentro que el código escrito en un lenguaje dinámico como python se enreda mas rapido. En parte, eso se debe a que es mucho más rápido escribir código en un lenguaje dinámico y eso lleva a atajos y peor diseño, al menos en mi caso. En parte es porque tengo IntelliJ para una refactorización rápida y fácil cuando uso Java, que no tengo para python.

La respuesta habitual a eso es probar las pruebas. Se supone que debe tener un amplio conjunto de pruebas unitarias y ejecutarlo con frecuencia, particularmente antes de que una nueva versión entre en línea.

Los defensores de los lenguajes de tipo dinámico hacen que sea necesario probarlo de todos modos porque incluso en un lenguaje de tipo estático, la conformidad con las reglas crudas del sistema de tipos cubre solo una pequeña parte de lo que puede salir mal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top