De algo como esto:
print(get_indentation_level())
print(get_indentation_level())
print(get_indentation_level())
Me gustaría obtener algo como esto:
1
2
3
¿Puede el código leerse de esta manera?
Todo lo que quiero es que la salida de las partes más anidadas del código esté más anidada. De la misma manera que esto hace que el código sea más fácil de leer, haría que la salida sea más fácil de leer.
Por supuesto, podría implementar esto manualmente, usando, por ejemplo .format()
, pero lo que tenía en mente era una función de impresión personalizada que vería print(i*' ' + string)
dónde i
está el nivel de sangría. Esta sería una forma rápida de hacer una salida legible en mi terminal.
¿Hay una mejor manera de hacer esto que evite el formato manual minucioso?
python
reflection
metaprogramming
indentation
tokenize
Fab von Bellingshausen
fuente
fuente
get_indentation_level()
enunciado en tu código. Puedes hacerprint(3)
lo mismo o lo que sea directamente. Lo que podría ser más interesante es el nivel actual de anidamiento en la pila de llamadas de función.depth
parámetro y agregarle el valor apropiado según sea necesario cuando lo pase a otras funciones. No es probable que la anidación de su código corresponda limpiamente a la sangría que desea de su salida.Respuestas:
Si desea una sangría en términos de nivel de anidación en lugar de espacios y pestañas, las cosas se ponen difíciles. Por ejemplo, en el siguiente código:
la llamada a
get_nesting_level
está anidada en un nivel de profundidad, a pesar del hecho de que no hay espacios en blanco iniciales en la línea de laget_nesting_level
llamada. Mientras tanto, en el siguiente código:la llamada a
get_nesting_level
está anidada a cero niveles de profundidad, a pesar de la presencia de espacios en blanco iniciales en su línea.En el siguiente código:
las dos llamadas a
get_nesting_level
están en diferentes niveles de anidación, a pesar de que el espacio en blanco inicial es idéntico.En el siguiente código:
¿Es eso cero niveles anidados, o uno? En términos de
INDENT
yDEDENT
tokens en la gramática formal, tiene cero niveles de profundidad, pero es posible que no sienta lo mismo.Si desea hacer esto, tendrá que tokenizar todo el archivo hasta el punto de la llamada y contar
INDENT
yDEDENT
tokens. Eltokenize
módulo sería muy útil para tal función:fuente
get_nesting_level()
se llama dentro de esa llamada de función: devuelve el nivel de anidación dentro de esa función. ¿Podría reescribirse para devolver el nivel de anidación 'global'?while
ywith
, eso sería factible, pero no es lo que solicitó, y cambiar la pregunta para hacer algo diferente en este momento Sería una mala idea.linecache
módulo para cosas como esta, sin embargo, se utiliza para imprimir trazas y puede manejar módulos importados de archivos zip y otros trucos de importación extraños)linecache
podría ser bueno para reducir la cantidad de E / S de archivo (y gracias por recordármelo), pero si comenzara a optimizar eso, me molestaría cómo estamos volviendo a tokenizar el mismo archivo de forma redundante para repeticiones de misma llamada o para múltiples sitios de llamadas dentro del mismo archivo. Hay varias maneras en que podríamos optimizar eso también, pero no estoy seguro de cuánto realmente quiero sintonizar y a prueba de balas esta locura.Sí, eso es definitivamente posible, aquí hay un ejemplo de trabajo:
fuente
print('{Space}'*get_indentation_level(), x)
Puede usar
sys.current_frame.f_lineno
para obtener el número de línea. Luego, para encontrar el número de nivel de sangría, necesita encontrar la línea anterior con cero sangría, luego restando el número de línea actual del número de esa línea obtendrá el número de sangría:Manifestación:
Si desea el número del nivel de sangría basado en las líneas anteriores con
:
solo puede hacerlo con un pequeño cambio:Manifestación:
Y como respuesta alternativa aquí hay una función para obtener el número de sangría (espacio en blanco):
fuente
:
hasta que encontremos la línea con sangría cero, ¡Mira la edición!{3:4, \n 2:get_ind_num()}
Para resolver el problema "real" que condujo a su pregunta, podría implementar un administrador de contexto que realice un seguimiento del nivel de sangría y haga que la
with
estructura de bloques en el código corresponda a los niveles de sangría de la salida. De esta forma, la sangría del código aún refleja la sangría de salida sin acoplar demasiado los dos. Todavía es posible refactorizar el código en diferentes funciones y tener otras sangrías basadas en la estructura del código que no interfiera con la sangría de salida.Salida:
fuente
fuente