python exception error-handling indentation code-formatting

python - Estoy obteniendo un IndentationError. ¿Cómo lo soluciono?



exception error-handling (4)

Tengo un script de Python:

if True: if False: print(''foo'') print(''bar'')

Sin embargo, cuando intento ejecutar mi script, Python genera un IndentationError :

File "script.py", line 4 print(''bar'') ^ IndentationError: unindent does not match any outer indentation level

Seguí jugando con mi programa y también pude producir otros tres errores:

  • IndentationError: unexpected indent
  • IndentationError: expected an indented block
  • TabError: inconsistent use of tabs and spaces in indentation

¿Qué significan estos errores? ¿Qué estoy haciendo mal? ¿Cómo puedo arreglar mi código?


Sublime Text 3

Si sucede que codifica en Sublime Text 3, esto podría ayudarlo con los problemas de sangría

En Sublime Text, mientras edita un archivo Python:

Menú Sublime Text > Preferencias > Configuración - Especificación de sintaxis :

Python.sublime-settings

{ "tab_size": 4, "translate_tabs_to_spaces": true }


¿Por qué importa la sangría?

En Python, la sangría se usa para delimitar bloques de código . Esto es diferente de muchos otros lenguajes que usan llaves {} para delimitar bloques como Java, Javascript y C. Debido a esto, los usuarios de Python deben prestar mucha atención a cuándo y cómo sangran su código porque el espacio en blanco es importante.

Cuando Python encuentra un problema con la sangría de su programa, genera una excepción llamada TabError o TabError .

Una pequeña historia

Las razones históricas por las que Python usa la sangría frente a las llaves rizadas posiblemente más comúnmente aceptadas {} se resumen en un artículo de la historia de Python por Guido van Rossum , el creador de Python:

El uso de la sangría de Python proviene directamente de ABC, pero esta idea no se originó con ABC: ya había sido promovida por Donald Knuth y era un concepto bien conocido de estilo de programación. (El lenguaje de programación occam también lo usó). Sin embargo, los autores de ABC inventaron el uso del colon que separa la cláusula de entrada del bloque sangrado. Después de las primeras pruebas de usuario sin los dos puntos, se descubrió que el significado de la sangría no estaba claro para los principiantes que aprendían los primeros pasos de la programación. La adición del colon lo aclaró significativamente: el colon de alguna manera llama la atención sobre lo que sigue y une las frases anteriores y posteriores de la manera correcta.

¿Cómo sangro mi código?

La regla básica para sangrar el código Python (considerando que trata el programa completo como un "bloque básico") es: La primera instrucción en un bloque básico, y cada instrucción posterior después de la misma debe sangrarse por la misma cantidad.

Entonces, técnicamente, el siguiente programa de Python es correcto:

def perm(l): # Compute the list of all permutations of l if len(l) <= 1: return [l] r = [] for i in range(len(l)): s = l[:i] + l[i+1:] p = perm(s) for x in p: r.append(l[i:i+1] + x) return r

Sin embargo, como probablemente pueda deducir de lo anterior, la sangría aleatoria de su código es extremadamente difícil de leer y seguir el flujo del programa. Es mejor ser coherente y seguir un estilo.

PEP8 - La guía de estilo de Python - recomienda que se usen cuatro espacios por nivel de sangría :

Use 4 espacios por nivel de sangría.

Es decir, cada instrucción que está comenzando un nuevo bloque y cada instrucción posterior en el nuevo bloque, debe tener sangría a cuatro espacios del nivel de sangría actual . Aquí está el programa anterior sangrado de acuerdo con la guía de estilo PEP8:

def perm(l): # Compute the list of all permutations of l if len(l) <= 1: return [l] r = [] for i in range(len(l)): s = l[:i] + l[i+1:] p = perm(s) for x in p: r.append(l[i:i+1] + x) return r

¿Puedo seguir usando pestañas?

Python se da cuenta de que algunas personas todavía prefieren las pestañas sobre los espacios y que el código heredado puede usar pestañas en lugar de espacios, por lo que permite el uso de pestañas como sangría. PEP8 toca este tema :

Los espacios son el método de sangría preferido.

Las pestañas deben usarse únicamente para mantener la coherencia con el código que ya está sangrado con pestañas.

Sin embargo, tenga en cuenta que la única gran advertencia es no utilizar pestañas y espacios para la sangría . Hacerlo puede causar todo tipo de errores de sangría difíciles de depurar. Python expande las pestañas a la siguiente octava columna, pero si su editor está configurado en un tamaño de pestaña de 4 columnas, o si usa espacios y pestañas, puede producir fácilmente un código sangrado que se vea bien en su editor, pero Python se negará correr. El compilador de Python 3 rechaza explícitamente cualquier programa que contenga una mezcla ambigua de pestañas y espacios, generalmente al generar un TabError . Sin embargo, de forma predeterminada, la mezcla de pestañas y espacios todavía está permitida en Python 2, pero se recomienda no utilizar esta "característica". Use los -tt línea de comando -t y -tt para forzar a Python 2 a generar una advertencia o (preferiblemente) un error respectivamente. PEP8 también discute este tema :

Python 3 no permite mezclar el uso de pestañas y espacios para la sangría.

El código de Python 2 sangrado con una mezcla de pestañas y espacios debe convertirse para usar espacios exclusivamente.

Al invocar al intérprete de línea de comandos de Python 2 con la opción -t, emite advertencias sobre el código que mezcla ilegalmente pestañas y espacios. Al usar -tt, estas advertencias se convierten en errores. ¡Estas opciones son muy recomendables!

¿Qué significa "IndentationError: sangría inesperada"?

Problema

Este error ocurre cuando una declaración se sangra innecesariamente o su sangría no coincide con la sangría de las declaraciones anteriores en el mismo bloque. Por ejemplo, la primera declaración en el siguiente programa está innecesariamente sangrada:

>>> print(''Hello'') # this is indented File "<stdin>", line 1 print(''Hello'') # this is indented ^ IndentationError: unexpected indent

En este ejemplo, la línea can_drive = True en el bloque if no coincide con la sangría de ninguna declaración anterior:

>>> age = 10 >>> can_drive = None >>> >>> if age >= 18: ... print(''You can drive'') ... can_drive = True # incorrectly indented File "<stdin>", line 3 can_drive = True # incorrectly indented ^ IndentationError: unexpected indent

Fijar

La solución para este error es primero asegurarse de que la línea problemática incluso necesite sangrarse. Por ejemplo, el ejemplo anterior que usa print se puede arreglar simplemente desangrando la línea:

>>> print(''Hello'') # simply unindent the line Hello

Sin embargo, si está seguro de que la línea debe sangrarse, la sangría debe coincidir con la de una declaración anterior en el mismo bloque. En el segundo ejemplo anterior usando if , podemos corregir el error asegurándonos de que la línea con can_drive = True esté sangrada al mismo nivel que las declaraciones anteriores en el cuerpo if :

>>> age = 10 >>> can_drive = None >>> >>> if age >= 18: ... print(''You can drive'') ... can_drive = True # indent this line at the same level. ...

¿Qué significa "IndentationError: se esperaba un bloque sangrado"?

Problema

Este error ocurre cuando Python ve el ''encabezado'' para una declaración compuesta, como if <condition>: o while <condition>: pero el cuerpo o bloque de la declaración compuesta nunca se define. Por ejemplo, en el siguiente código comenzamos una declaración if , pero nunca definimos un cuerpo para la declaración:

>>> if True: ... File "<stdin>", line 2 ^ IndentationError: expected an indented block

En este segundo ejemplo, comenzamos a escribir un bucle for , pero olvidamos sangrar el cuerpo del bucle for . Entonces Python aún espera un bloque sangrado para el cuerpo del bucle for :

>>> names = [''sarah'', ''lucy'', ''michael''] >>> for name in names: ... print(name) File "<stdin>", line 2 print(name) ^ IndentationError: expected an indented block

Los comentarios no cuentan como cuerpos:

>>> if True: ... # TODO ... File "<stdin>", line 3 ^ IndentationError: expected an indented block

Fijar

La solución para este error es simplemente incluir un cuerpo para la declaración compuesta.

Como se muestra arriba, un error común de los nuevos usuarios es que se olvidan de sangrar el cuerpo. Si este es el caso, asegúrese de que cada enunciado destinado a ser incluido en el cuerpo del enunciado compuesto esté sangrado al mismo nivel bajo el comienzo del enunciado compuesto. Aquí está el ejemplo anterior arreglado:

>>> names = [''sarah'', ''lucy'', ''michael''] >>> for name in names: ... print(name) # The for loop body is now correctly indented. ... sarah lucy michael

Otro caso común es que, por alguna razón, un usuario puede no querer definir un cuerpo real para la declaración compuesta, o el cuerpo puede ser comentado. En este caso, se puede usar la sentencia pass . La declaración de pass se puede usar en cualquier lugar donde Python espere una o más declaraciones como marcador de posición. De la documentación para el pass :

pass es una operación nula: cuando se ejecuta, no sucede nada. Es útil como marcador de posición cuando se requiere una declaración sintácticamente, pero no es necesario ejecutar ningún código, por ejemplo:

def f(arg): pass # a function that does nothing (yet) class C: pass # a class with no methods (yet)

Aquí está el ejemplo anterior con la instrucción if fijada usando la palabra clave pass :

>>> if True: ... pass # We don''t want to define a body. ... >>>

¿Qué significa "IndentationError: unindent no coincide con ningún nivel de sangría externa"?

Problema

Este error ocurre cuando desinfecta una declaración, pero ahora el nivel de sangría de esa declaración no coincide con el de ninguna declaración anterior. Por ejemplo, en el siguiente código, desanimamos la segunda llamada para print . Sin embargo, el nivel de sangría no coincide con el de ninguna declaración anterior:

>>> if True: ... if True: ... print(''yes'') ... print() File "<stdin>", line 4 print() ^ IndentationError: unindent does not match any outer indentation level

Este error es especialmente difícil de detectar porque incluso un espacio hará que su código falle.

Fijar

La solución es asegurarse de que cuando desinfecte una declaración, el nivel de sangría coincida con el de una declaración anterior. Considere el ejemplo anterior una vez más. En el ejemplo, quiero que la segunda llamada para imprimir esté en el primer cuerpo de declaraciones if . Entonces, debo asegurarme de que el nivel de sangría de esa línea coincida con el de las declaraciones anteriores en el primer cuerpo de la declaración if :

>>> if True: ... if True: ... print(''yes'') ... print() # indentation level now matches former statement''s level. ... yes >>>

Todavía recibo un IndentationError pero mi programa parece estar correctamente sangrado. ¿Qué debo hacer?

Si su programa visualmente parece tener una sangría correcta, pero aún obtiene un IndentationError lo más probable es que haya mezclado pestañas con espacios . Esto a veces hará que Python genere errores extraños. Consulte la subsección Casos especiales en ¿Qué significa "TabError: uso inconsistente de tabulaciones y espacios en sangría"? para una explicación más profunda del problema.

¿Qué significa "TabError: uso inconsistente de tabulaciones y espacios en sangría"?

Problema

Este error solo ocurre cuando intentas mezclar pestañas y espacios como caracteres de sangría. Como se dijo anteriormente, Python no permitirá que su programa contenga una mezcla de pestañas y espacios, y generará la excepción específica TabError si encuentra que tiene. Por ejemplo, en el siguiente programa, se usa una combinación de pestañas y espacios para la sangría:

>>> if True: ... if True: ... print() ... print() ... print() File "<stdin>", line 5 print() ^ TabError: inconsistent use of tabs and spaces in indentation

Aquí hay una imagen que muestra visualmente el espacio en blanco en el programa anterior. Los puntos grises son espacios y las flechas grises son pestañas:

Podemos ver que de hecho tenemos espacios mixtos y pestañas para la sangría.

Casos especiales

Nota: Python no siempre TabError un TabError si TabError pestañas y espacios en su programa. Si la sangría del programa no es ambigua, Python permitirá que se mezclen pestañas y espacios. Por ejemplo:

>>> if True: ... if True: # tab ... pass # tab, then 4 spaces ... >>>

Y a veces Python simplemente se ahoga en la combinación de pestañas y espacios y genera erróneamente una excepción TabError cuando un TabError sería más apropiado. Otro ejemplo:

>>> if True: ... pass # tab ... pass # 4 spaces File "<stdin>", line 3 pass # 4 spaces ^ IndentationError: unindent does not match any outer indentation level

Como puede ver, ejecutar su código de esta manera puede crear errores misteriosos. A pesar de que el programa visualmente parece estar bien, Python se confundió al tratar de analizar las pestañas y los espacios utilizados para la sangría y se equivocó.

Estos son excelentes ejemplos que demuestran por qué nunca mezclar tabulaciones y espacios y hacer uso de los -tt intérprete -t y -tt cuando se usa Python 2.

Fijar

Si su programa es corto, probablemente la solución más fácil y rápida es simplemente volver a sangrar el programa. Asegúrese de que cada declaración esté sangrada por cuatro espacios por nivel de sangría (consulte ¿Cómo sangro mi código? ).

Sin embargo, si ya tiene un programa grande en el que ha mezclado pestañas y espacios, existen herramientas automatizadas que pueden usarse para convertir toda su sangría en solo espacios.

Muchos editores como PyCharm y SublimeText tienen opciones para convertir automáticamente las pestañas en espacios. También hay varias herramientas en línea, como Tabs To Spaces o Browserling que le permiten volver a sangrar rápidamente su código. También hay herramientas escritas en Python. autopep8 por ejemplo, también puede volver a sangrar automáticamente su código y otros errores de sangría.

Sin embargo, incluso las mejores herramientas a veces no podrán corregir todos sus errores de sangría y tendrá que corregirlos manualmente. Por eso es importante sangrar siempre correctamente el código desde el principio.

Una nota sobre los problemas de sangría relacionados con "SyntaxError"

Aunque no es frecuente, a veces se SyntaxError ciertas excepciones de SyntaxError debido a una sangría incorrecta. Por ejemplo, mira el siguiente código:

if True: pass pass # oops! this statement should be indented!. else: pass

Cuando se ejecuta el código anterior, se SyntaxError is raised un SyntaxError is raised :

Traceback (most recent call last): File "python", line 4 else: ^ SyntaxError: invalid syntax

Aunque Python genera un SyntaxError , el verdadero problema con el código anterior es que la segunda instrucción de pass debe tener sangría. Debido a que el segundo pass no está sangrado, Python no se da cuenta de que la declaración if anterior y la declaración else deben estar conectadas.

La solución para este tipo de error es simplemente volver a sangrar correctamente su código. Para ver cómo sangrar correctamente su código, consulte la sección ¿Cómo sangro mi código? .

Todavía estoy teniendo dificultades con la sintaxis de sangría de Python. ¿Qué debo hacer?

No se desanime si todavía está luchando. Puede llevar tiempo acostumbrarse a las reglas de sintaxis de espacios en blanco de Python. Aquí hay algunos consejos para ayudar:

  • Obtenga un editor que le dirá cuando tenga un error de sangría. Algunos productos son como se dijo anteriormente, PyCharm , SublimeText y Jupyter Notebook .
  • Cuando sangra su código, cuente en voz alta cuántas veces presiona la barra espaciadora (o la tecla tab). Por ejemplo, si necesita sangrar una línea por cuatro espacios, diría en voz alta " uno , dos , tres , cuatro " mientras presiona simultáneamente la barra espaciadora cada vez. Suena tonto, pero ayuda a entrenar a tu cerebro a pensar en qué tan profundo estás sangrando tu código.
  • Si tiene un editor, vea si tiene una opción para convertir automáticamente las pestañas en espacios.
  • Ver el código de otros. Explore github o github y vea ejemplos de código Python.
  • Solo escribe el código. Esa es la mejor manera de mejorar. Cuanto más escriba el código Python, mejor será.

Recursos utilizados


Solución rápida para usuarios de Sublime:

  1. Presione Ctrl-H para acceder a Buscar y reemplazar
  2. En Buscar: espacios de tipo 4
  3. En Reemplazar: copie y pegue una pestaña desde algún lugar de su código Haga clic en Reemplazar todo

Verás, tienes un pequeño error.

if True: if False: print(''foo'') print(''bar'')

Se suponía que debías hacer:

if True: if False: print(''foo'') print(''bar'')

Como puede ver, su impresión solo tiene sangría de 3 espacios, se supone que tiene sangría de 4 espacios.