2009-06-22 6 views
14

Mi historial es C y C++. Me gusta mucho Python, pero hay un aspecto del mismo (y de otros lenguajes interpretados, supongo) con el que es difícil trabajar cuando estás acostumbrado a los lenguajes compilados.¿Cómo puedo asegurarme de que todo mi código Python se "compila"?

Cuando escribo algo en Python y llego al punto en el que puedo ejecutarlo, aún no hay garantía de que no queden errores específicos del idioma. Para mí eso significa que no puedo confiar únicamente en mi defensa en tiempo de ejecución (pruebas rigurosas de entrada, afirmaciones, etc.) para evitar bloqueos, porque en 6 meses cuando finalmente se ejecuta algún código bueno, podría resquebrajarse debido a algún error estúpido .

Claramente, un sistema debe probarse lo suficiente para garantizar que todo el código se haya ejecutado, pero la mayoría de las veces uso Python para scripts internos y herramientas pequeñas, que por supuesto nunca reciben la atención de control de calidad que necesitan. Además, algunos códigos son tan simples que (si su fondo es C/C++) sabe que funcionará bien siempre que se compile (por ejemplo, getter-methods dentro de las clases, generalmente un retorno simple de una variable miembro).

Entonces, mi pregunta es obvia: ¿hay alguna forma (con una herramienta especial o algo así) de asegurarme de que todo el código en mi script de Python se "compilará" y se ejecutará?

+0

Precioso ... Soy un chico C/C++ nuevo en Python también, y este problema me ha frustrado sin fin. Sin embargo, nunca pensé en preguntar sobre una solución, no creía que pudiera existir. –

Respuesta

21

Mira PyChecker y PyLint.

Aquí es una salida de ejemplo pylint , derivado del programa trivial:

print a 

Como se puede ver, se detecta la variable no definida, que py_compile no (deliberadamente)

in foo.py: 

************* Module foo 
C: 1: Black listed name "foo" 
C: 1: Missing docstring 
E: 1: Undefined variable 'a' 


... 

|error  |1  |1  |=   | 
. 10

ejemplo trivial de por qué pruebas no son lo suficientemente buenos, incluso si cubren "todas las líneas":

bar = "Foo" 
foo = "Bar" 
def baz(X): 
    return bar if X else fo0 

print baz(input("True or False: ")) 

EDIT: PyChecker maneja el ternario para mí:

Processing ternary... 
True or False: True 
Foo 

Warnings... 

ternary.py:6: No global (fo0) found 
ternary.py:8: Using input() is a security problem, consider using raw_input() 
+1

Buena recomendación de pychecker y pylint. pyflakes también es bueno porque es muy rápido, y la versión del tronco svn capturará las variables locales no utilizadas. En cuanto a probar "cada línea", creo que al menos debes probar cada "ruta". Eso habría atrapado tu ejemplo de explosión. –

+1

Funciona muy bien Matthew, gracias! – sharkin

+0

Es imposible identificar (y luego probar) cada ruta lógica posible, porque eso es equivalente al problema de detención (http://en.wikipedia.org/wiki/Code_coverage). –

1

Creo que lo que está buscando es la cobertura de línea de prueba de código. Desea agregar pruebas a su secuencia de comandos que garantizará que todas sus líneas de código, o todas las que tenga tiempo, sean probadas. La prueba es una gran cantidad de trabajo, pero si desea que el tipo de garantía de que usted está pidiendo, no hay almuerzo gratis, lo siento :(.

+1

Él no está buscando el código para pasar las pruebas. Él ya dijo, "en 6 meses cuando finalmente se ejecute el código por lo demás agradable, podría simplemente romperse debido a algún error tipográfico". Las pruebas comprueban si el código hace "lo correcto" para algún conjunto de entrada finito, no si usa sintaxis válida en todo (lo que OP quiere) –

+1

No pasará muchas pruebas si tiene errores tipográficos. Si su cobertura toca cada línea de código (no todas las rutas lógicas), estará razonablemente seguro de que funcionará de manera confiable. –

+0

-1. Lo siento Adam, la pregunta sugiere que tales esfuerzos de QA son bastante poco realistas, por lo que la respuesta es de poca ayuda. – sharkin

0

Su código se compila en realidad cuando lo ejecuta, el tiempo de ejecución de Python se quejará si hay un error de sintaxis en el código. Comparado con lenguajes compilados estáticamente como C/C++ o Java, no verifica si los nombres y tipos de variables son correctos, para eso necesita ejecutar el código (por ejemplo, con pruebas automatizadas).

+1

-1. Parece que en realidad hay herramientas para descubrir errores como ese, y por lo tanto no es necesario ejecutar el código para descubrirlos. – sharkin

1

Si está utilizando Eclipse con Pydev como un IDE, puede marcar muchos errores tipográficos para usted con squigglies rojos de inmediato, y también tiene integración de Pylint. Por ejemplo:

foo = 5 
print food 

se marcarán como "Variable indefinida: comida". Por supuesto, esto no siempre es exacto (quizás los alimentos se definieron antes usando setattr u otras técnicas exóticas), pero funciona bien la mayor parte del tiempo.

En general, solo puede analizar estáticamente su código en la medida en que su código sea realmente estático; Cuanto más dinámico sea tu código, más necesitarás pruebas automatizadas.

2

Otros han mencionado herramientas como PyLint que son bastante buenas, pero lo que falta es que simplemente no es posible hacerlo al 100%. De hecho, es posible que ni siquiera quieras hacerlo. Parte del beneficio para la dinámica de Python es que puedes hacer cosas locas como insertar nombres en el ámbito local a través de un acceso de diccionario.

Lo que se reduce a esto es que si quieres una forma de detectar errores de tipo en tiempo de compilación, no deberías usar Python. Una elección de idioma siempre implica un conjunto de concesiones. Si eliges Python sobre C, ten en cuenta que estás intercambiando un sistema de tipo fuerte para un desarrollo más rápido, mejor manipulación de cadenas, etc.

Cuestiones relacionadas