파이썬 코드 라인이 들여쓰기 중첩 수준을 알 수 있습니까?
다음과 같은 것으로부터:
print(get_indentation_level())
print(get_indentation_level())
print(get_indentation_level())
저는 다음과 같은 것을 얻고 싶습니다.
1
2
3
코드가 이런 식으로 스스로 읽을 수 있습니까?
내가 원하는 것은 코드의 더 중첩된 부분에서 더 중첩된 출력되는 것입니다.이것은 코드를 읽기 쉽게 만드는 것과 마찬가지로 출력을 읽기 쉽게 만듭니다.
물론 이것을 수동으로 구현할 수 있습니다. 예를 들어,.format()
하지만 제가 염두에 둔 것은 맞춤형 인쇄 기능으로,print(i*' ' + string)
어디에i
들여쓰기 수준입니다.이것은 내 단말기에서 읽을 수 있는 출력을 빠르게 할 수 있는 방법입니다.
번거로운 수동 포맷을 피할 수 있는 더 좋은 방법이 있습니까?
공백과 탭이 아닌 중첩 수준의 관점에서 들여쓰기를 원하는 경우에는 상황이 까다로워집니다.예를 들어, 다음 코드에서:
if True:
print(
get_nesting_level())
로의 요청.get_nesting_level
라인에 선행 공백이 없음에도 불구하고 실제로 한 단계 깊이로 중첩됩니다.get_nesting_level
그 사이에 다음 코드로.
print(1,
2,
get_nesting_level())
로의 요청.get_nesting_level
선에 선행 공백이 있음에도 불구하고 0단계 깊이로 중첩됩니다.
다음 코드:
if True:
if True:
print(get_nesting_level())
if True:
print(get_nesting_level())
에 대한 두 번의 요청get_nesting_level
선행 공백이 동일함에도 불구하고 서로 다른 중첩 수준에 있습니다.
다음 코드:
if True: print(get_nesting_level())
그게 중첩된 0레벨입니까, 아니면 1레벨입니까?측면에서.INDENT
그리고.DEDENT
공식 문법의 토큰은 깊이가 0이지만, 당신은 같은 느낌이 들지 않을 수 있습니다.
이렇게 하려면 전체 파일을 통화 시점까지 토큰화해야 합니다.INDENT
그리고.DEDENT
토큰모듈은 다음과 같은 기능에 매우 유용합니다.
import inspect
import tokenize
def get_nesting_level():
caller_frame = inspect.currentframe().f_back
filename, caller_lineno, _, _, _ = inspect.getframeinfo(caller_frame)
with open(filename) as f:
indentation_level = 0
for token_record in tokenize.generate_tokens(f.readline):
token_type, _, (token_lineno, _), _, _ = token_record
if token_lineno > caller_lineno:
break
elif token_type == tokenize.INDENT:
indentation_level += 1
elif token_type == tokenize.DEDENT:
indentation_level -= 1
return indentation_level
네, 확실히 가능합니다. 다음은 실제 사례입니다.
import inspect
def get_indentation_level():
callerframerecord = inspect.stack()[1]
frame = callerframerecord[0]
info = inspect.getframeinfo(frame)
cc = info.code_context[0]
return len(cc) - len(cc.lstrip())
if 1:
print get_indentation_level()
if 1:
print get_indentation_level()
if 1:
print get_indentation_level()
사용할 수 있습니다.sys.current_frame.f_lineno
라인 번호를 얻기 위해.그런 다음 들여쓰기 수준의 수를 찾기 위해 들여쓰기가 0인 이전 줄을 찾은 다음 해당 줄의 번호에서 현재 줄 번호를 빼면 들여쓰기 수를 얻을 수 있습니다.
import sys
current_frame = sys._getframe(0)
def get_ind_num():
with open(__file__) as f:
lines = f.readlines()
current_line_no = current_frame.f_lineno
to_current = lines[:current_line_no]
previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
return current_line_no - previous_zoro_ind
데모:
if True:
print get_ind_num()
if True:
print(get_ind_num())
if True:
print(get_ind_num())
if True: print(get_ind_num())
# Output
1
3
5
6
다음과 같은 이전 라인을 기준으로 들여쓰기 수준의 수를 원하는 경우:
약간의 변화만으로도 할 수 있습니다.
def get_ind_num():
with open(__file__) as f:
lines = f.readlines()
current_line_no = current_frame.f_lineno
to_current = lines[:current_line_no]
previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
return sum(1 for line in lines[previous_zoro_ind-1:current_line_no] if line.strip().endswith(':'))
데모:
if True:
print get_ind_num()
if True:
print(get_ind_num())
if True:
print(get_ind_num())
if True: print(get_ind_num())
# Output
1
2
3
3
또한 다음은 들여쓰기 수(흰색 공간)를 구하는 함수입니다.
import sys
from itertools import takewhile
current_frame = sys._getframe(0)
def get_ind_num():
with open(__file__) as f:
lines = f.readlines()
return sum(1 for _ in takewhile(str.isspace, lines[current_frame.f_lineno - 1]))
하기 위해, 할 수 , 질으로실이 "제기를하해" "결위해의" "문문고다" "제는수" "도을하" "니행있" "트습컨" "스을텍" "수하다를" "할리" "현자관" "구음" "준적추수는어" "지" "▁the다니▁which" "실" "real▁to▁and있습manager"" "▁a▁problem▁you▁implement▁that수" "▁make" "▁could" "▁keeps" "▁solve▁question▁contextwith
코드의 블록 구조는 출력의 들여쓰기 수준에 해당합니다.이러한 방식으로 코드 들여쓰기는 둘 다 너무 많이 결합하지 않고 출력 들여쓰기를 반영합니다.코드를 다른 함수로 리팩터링하고 코드 구조에 기반한 다른 들여쓰기가 출력 들여쓰기를 방해하지 않도록 할 수 있습니다.
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
class IndentedPrinter(object):
def __init__(self, level=0, indent_with=' '):
self.level = level
self.indent_with = indent_with
def __enter__(self):
self.level += 1
return self
def __exit__(self, *_args):
self.level -= 1
def print(self, arg='', *args, **kwargs):
print(self.indent_with * self.level + str(arg), *args, **kwargs)
def main():
indented = IndentedPrinter()
indented.print(indented.level)
with indented:
indented.print(indented.level)
with indented:
indented.print('Hallo', indented.level)
with indented:
indented.print(indented.level)
indented.print('and back one level', indented.level)
if __name__ == '__main__':
main()
출력:
0
1
Hallo 2
3
and back one level 2
>>> import inspect
>>> help(inspect.indentsize)
Help on function indentsize in module inspect:
indentsize(line)
Return the indent size, in spaces, at the start of a line of text.
언급URL : https://stackoverflow.com/questions/39172306/can-a-line-of-python-code-know-its-indentation-nesting-level
'programing' 카테고리의 다른 글
MySQL: 다른 datetime 필드에 datetime 삽입 (0) | 2023.08.24 |
---|---|
**kwargs 매개 변수를 문서화하는 올바른 방법은 무엇입니까? (0) | 2023.08.24 |
웹 사이트에서 IE9이 호환 모드로 전환되는 이유는 무엇입니까? (0) | 2023.08.24 |
IE에서 .change()를 인식하도록 jQuery를 가져오는 중 (0) | 2023.08.24 |
CSS를 사용하여 사용자 지정 글꼴을 사용하시겠습니까? (0) | 2023.08.24 |