De algo assim:
print(get_indentation_level())
print(get_indentation_level())
print(get_indentation_level())
Eu gostaria de obter algo parecido com isto:
1
2
3
O código pode se ler dessa maneira?
Tudo o que eu quero é que a saída das partes mais aninhadas do código seja mais aninhada. Da mesma forma que isso facilita a leitura do código, a saída é mais fácil de ler.
É claro que eu poderia implementar isso manualmente, usando, por exemplo .format()
, mas o que eu tinha em mente era uma função de impressão personalizada que seria print(i*' ' + string)
onde i
está o nível de indentação. Essa seria uma maneira rápida de obter uma saída legível no meu terminal.
Existe uma maneira melhor de fazer isso que evite a formatação manual cuidadosa?
python
reflection
metaprogramming
indentation
tokenize
Fab von Bellingshausen
fonte
fonte
get_indentation_level()
declaração no seu código. Você também pode fazer o queprint(3)
quer que seja diretamente. O que pode ser mais interessante é o nível atual de aninhamento na pilha de chamadas de função.depth
parâmetro e adicionando o valor apropriado conforme necessário quando você o passa para outras funções. É provável que o aninhamento do seu código não corresponda corretamente ao recuo que você deseja da saída.Respostas:
Se você deseja recuo em termos de nível de aninhamento, em vez de espaços e guias, as coisas ficam complicadas. Por exemplo, no seguinte código:
a chamada para
get_nesting_level
está realmente aninhada em um nível, apesar do fato de que não há espaços em branco à esquerda na linha daget_nesting_level
chamada. Enquanto isso, no seguinte código:a chamada para
get_nesting_level
está aninhada com zero nível de profundidade, apesar da presença de espaços em branco à esquerda em sua linha.No código a seguir:
as duas chamadas
get_nesting_level
estão em diferentes níveis de aninhamento, apesar do espaço em branco inicial ser idêntico.No código a seguir:
esses níveis zero aninhados ou um? Em termos
INDENT
eDEDENT
tokens na gramática formal, os níveis são zero, mas você pode não se sentir da mesma maneira.Se você quiser fazer isso, terá que tokenizar o arquivo inteiro até o ponto da chamada e contar
INDENT
eDEDENT
tokens. Otokenize
módulo seria muito útil para essa função:fonte
get_nesting_level()
é chamado nessa chamada de função - ele retorna o nível de aninhamento nessa função. Poderia ser reescrito para retornar o nível de aninhamento 'global'?while
ewith
, isso seria possível, mas não é o que você pediu e alterando a pergunta para fazer algo diferente neste momento seria uma má ideia.linecache
módulo para coisas como esta embora - ele é usado para imprimir tracebacks, e pode lidar com módulos importados de arquivos zip e outros truques estranho importação)linecache
pode ser bom para reduzir a quantidade de E / S de arquivo (e obrigado por me lembrar disso), mas se eu começar a otimizar isso, ficaria incomodado com a redundância de tokenização do mesmo arquivo para repetições do arquivo mesma chamada ou para vários sites de chamada no mesmo arquivo. Existem várias maneiras de otimizar isso também, mas não tenho certeza do quanto eu realmente quero ajustar e proteger esta coisa louca.Sim, isso é definitivamente possível, aqui está um exemplo de trabalho:
fonte
print('{Space}'*get_indentation_level(), x)
Você pode usar
sys.current_frame.f_lineno
para obter o número da linha. Então, para encontrar o número do nível de recuo, você precisa encontrar a linha anterior com recuo zero e, subtraindo o número da linha atual do número dessa linha, você obterá o número de recuo:Demo:
Se você quiser o número do nível de indentação com base nas linhas anteriores,
:
basta fazê-lo com uma pequena alteração:Demo:
E como resposta alternativa, aqui está uma função para obter o número de indentação (espaço em branco):
fonte
:
até encontrarmos a linha com recuo zero, confira a edição!{3:4, \n 2:get_ind_num()}
Para resolver o problema "real" que leva à sua pergunta, você pode implementar um gerenciador de contexto que monitora o nível de
with
indentação e faz com que a estrutura do bloco no código corresponda aos níveis de indentação da saída. Dessa forma, o recuo do código ainda reflete o recuo da saída sem acoplar muito os dois. Ainda é possível refatorar o código em diferentes funções e ter outros recuos baseados na estrutura do código que não interferem no recuo da saída.Resultado:
fonte
fonte