Python 3.7 New Features

.

Python 3.7의 새로운 기능들

이 글은 다음 글을 번역한 글입니다.

Python 3.7이 공식적으로 배포되었습니다. 새로운 버전은 지난 2016년 9월부터 개발에 들어갔었고, 드디어 핵심 개발자들이 진행한 작업들의 결과물을 볼 수 있게 되었습니다!

이번에 발표된 새 버전에는 어떤 것들이 포함되어 있을까요? 공식 문서가 전체적으로 잘 설명해 주고 있긴 하지만, 이 글에서는 굵직굵직한 내용을 중심으로 깊게 다뤄볼 예정입니다. 대략적인 주제들은 다음과 같습니다.

  • 내장된 breakpoint()를 이용해 손쉽게 디버거에 접근하기.
  • Data 클래스들을 이용해 손쉽게 클래스 생성하기.
  • Module 속성에 커스텀된 방식으로 접근하기.
  • Type hinting에 대한 발전된 지원.
  • 보다 높은 정확도를 가지는 timing 함수들.

그리고 무엇보다도 Python 3.7은 빠릅니다.

이 글의 마지막 섹션에서는 Python 3.7의 다른 멋진 요소들과 더불어 속도와 관련된 내용을 더 보실 수 있습니다. 또한, 버전 업그레이드에 대한 몇 가지 조언 또한 보실 수 있습니다.

내장 breakpoint()

우리는 항상 완벽한 코드를 짜기 위해 노력하지만, 사실 이는 불가능에 가깝습니다. 그렇기 때문에 디버깅은 프로그래밍에 있어서 매우 중요한 부분입니다. Python 3.7은 새로운 내장함수 (built-in function)인 breakpoint()를 가지고 있습니다. 이는 파이썬 자체에 있어 어떤 새로운 기능을 추가한 것은 아니지만 디버거를 좀 더 유연하고 직관적으로 사용할 수 있도록 해줍니다.

만약 다음과 같이 버그가 있는 bugs.py 파일이 있다고 가정해 봅시다.

1
2
3
4
5
def divide(e, f):
    return f / e

a, b = 0, 1
print(divide(a, b))

이 코드를 실행하면 divide()함수 안에서 ZeroDivisionError가 발생하게 됩니다. 만약 당신이 코드를 인터럽트하고 디버거를 divide()함수 바로 위에 던져넣고 싶다고 생각해보죠. 이를 위해 이른바 breakpoint를 코드 내에 설정하면 될 것입니다.

1
2
3
def divide(e, f):
    # Insert breakpoint here
    return f / e

breakpoint는 일종의 신호로 코드 내에서 코드의 실행흐름을 잠시 멈추게 하고, 이를 통해 당신이 프로그램의 현재 상태를 둘러볼 수 있게 해줍니다. 그렇다면 어떻게 breakpoint를 원하는 곳에 위치시킬 수 있을까요? Python 3.6에서는 다음과 같은 방식을 사용했습니다.

1
2
3
def divide(e, f):
    import pdb; pdb.set_trace()
    return f / e

여기서 pdb는 기본 라이브러리로 포함되어 있는 파이썬 디버거입니다. Python 3.7에서는 이 방식 대신 새로 도입된 breakpoint() 함수를 이용해서 간단하게 사용할 수 있습니다.

1
2
3
def divide(e, f):
    breakpoint()
    return f / e

내부적으로 breakpoint()는 먼저 pdb를 임포트하고 pdb.set_trace()를 호출합니다. 이 방식을 이용하면 breakpoint()라는 기억하기 쉬운 방식으로 디버거를 호출할 수 있다는 것과 단순히 쳐야할 단어가 27자에서 12자로 줄었다는 장점이 있습니다. 그러나 무엇보다도 좋은 점은 breakpoint()자체를 커스텀할 수 있다는 점입니다.

_bugs.py_를 쉘에서 실행시키면 다음과 같이 됩니다.

1
2
3
4
$ python3.7 bugs.py
> /home/gahjelle/bugs.py(3)divide()
-> return f / e
(Pdb)

프로그램의 실행 흐름이 breakpoint()에 도달했을 때, 스크립트는 멈추게 되고 당신에게 PDB 디버깅 세션으로 들어가게 해줍니다. 이 상황에서 cENTER를 누르게 되면 스크립트를 계속해서 실행합니다. PDB와 디버깅에 대해서 좀 더 알고 싶다면 이 글을 참고하세요.

자 이제 당신이 버그를 다 고쳤다고 해봅시다. 분명히 당신은 이제 스크립트를 다시 실행시키겠지만, 디버깅이 스크립트의 실행을 멈춰세우는 것을 원하지 않을 것입니다. 물론 이를 breakpoint() 주석처리하는 방식으로 해결할 수도 있지만, PYTHONBREAKPOINT 환경변수를 사용하는 방식으로 해결할 수도 있습니다. 이 변수는 breakpoint()의 동작을 제어하고 PYTHONBREAKPOINT=0의 뜻은 breakpoint()의 호출을 모두 무시한다는 뜻입니다.

1
2
$ PYTHONBREAKPOINT=0 python3.7 bugs.py
ZeroDivisionError: division by zero

또 다른 커스텀할 수 있는 점은 PYTHONBREAKPOINT를 사용해서 PDB가 아닌 다른 디버거를 명시할 수 있다는 것입니다. 예를 들어 PuDB를 이용하는 경우에는 다음과 같이 할 수 있습니다.

1
$ PYTHONBREAKPOINT=pudb.set_trace python3.7 bugs.py

이를 위해서 물론 pudb 자체를 먼저 설치해야 합니다 (pip install pudb).