CodeZine(コードジン)

特集ページ一覧

EuroPython 2018参加レポート(1)~基調講演、Python 3.7の新機能、大規模コードベースにおける型アノテーション

  • LINEで送る
  • このエントリーをはてなブックマークに追加

目次

Python 3.7の新機能

 このセッションではPython 3.7の新機能の紹介がありました(Python 3.7の開発ロードマップはこちらからPEP-537)。

 セッションで紹介されたPython 3.7のリリース新機能について紹介します。

[PEP-553] Built-in breakpoint()

 Python 3.7から新たに組み込みブレークポイントが追加されました。

 これまでデバッガといえば次のようなものがありました。

  • pdb
  • ipdb
  • pudb
  • pdbpp

 しかし、ブレークポイントを設定する場合、下記のように記述をするため、これまでいくつかの問題点が挙げられていました。

従来のブレークポイントの設定
foo()
import pdb; pdb.set_trace()
bar()

問題点

  • 27文字と多く入力が大変
  • タイプミスをしやすい
  • Linterに一行の中に2つのステートメントが入っていると注意されることがある
  • プログラムからデバッガを起動するコードに一貫性がない

 これらの理由からデバッガの環境が複雑になったため、デバッガの汎用APIとして今回追加されたものが、breakpoint()です。

 これまでと同様に、コード中にbreakpoint()と記述することでデバッガを起動することができます。

 これにより共通のインターフェースでデバッガを使用することができるようになりました。

breakpoint()の使用例
def divide(e, f):
  breakpoint()
  return f / e

a, b = 0, 1
print(divide(a, b))
$ python bugs.py
> /tmp/bugs.py(3)divide()
-> return f / e
(pdb)

 上記のようにデバッグが可能になり、デフォルトでbreakpoint()pdb.set_trace()を使用します。

 また、PYTHONBREAKPOINTにより各種設定が可能です。

PYTHONBREAKPOINT=0 # デバッグを無効化
PYTHONBREAKPOINT='' or PYTHONBREAKPOINT= # デフォルトのpdbを使用
PYTHONBREAKPOINT=callable # 任意のデバッガを指定(例:pudb.set_trace)

[PEP-557] Data Classes

 Python 3.7からクラスに@dataclassを付与することで__init____repr____eq__等のメソッドを自動作成する機能が追加されました。

使用例
@dataclass
class Position:
  name: str
  latitude: float = 0.0
  longitude: float = 0.0

 特定のメソッドのみの有効化や無効化も引数を用いて指定ができます。

init=True # __init__
repr=True # __repr__
eq=True # __eq__
order=True # __lt__, __le__, __gt__, __ge__
frozen=False # __setattr__, __getattr__ ...
>>> @dataclass(frozen=True)
... class Person:
...   firstname: str
...   lastname: str
...   age: int
...
>>> person = Person('code', 'zine', 25)
>>> person.age = 26 # dataclasses.FrozenInstanceError: cannnot assign to field 'age'

[PEP-563] Postponed Evaluation of Annotations

 今まででは型の前方参照ができない問題があり、下記のようなコードは実行時に未定義となってしまいました。

class Node:
  def __init__(self, left: Node, right: Node) -> None:
    self.left = left
    self.right = right

-> NameError: name 'Node' is not defined

 しかし、Python 3.7ではannotationsを利用することで、実行時まで評価を遅延されることで型の前方参照ができるようになりました。

from __features_ import annotations

class Node:
  def __init__(self, left: Node, right: Node) -> None:
    self.left = left
    self.right = right

[PEP-564] Add new time functions with nanosecond resolution

 timeモジュールに6つのナノ精度の関数がサポートされました。

 従来、Pythonのfloat型は104日制限という問題があり、これは64bitのIEEE 754フォーマットの浮動小数点型は、この制限により104日以降にナノ秒の精度を失うという問題です。

 その問題以外にも、多くのベンチマーク計測などでは関数の呼び出し時間が100ns未満であることから、数ナノ秒の差の計測が重要となっていました。

 そこで、これらの問題を解決するために新たにナノ精度の関数がtimeモジュールに追加されました。

time.clock_gettime_ns
time.clock_settime_ns
time.monotonic_ns
time.perf_counter_ns
time.process_time_ns
time.time_ns

[PEP-565] Show DeprecationWarning in __main__

 Python3.2のDeprecationWarningはデフォルトで非表示となっていたため、開発者が非推奨であることに気がつくのが遅れるという問題がありました。

 そこで__main__でも表示されるように新たに変更されました。

Class 意味
FutureWarning デフォルトで常に警告を表示する
DeprecationWarning __main__とテスト時に警告を表示する
PendingDeprecationWarning テスト実行時のみ警告を表示する

[PEP-567] Context Variables

 非同期環境でも動作するコンテキスト変数としてcontextvarsモジュールとContext、ContextVarクラスが追加されました。

import contextvars

var = contextvars.ContextVar('var', default=42)
print('without context', var.get()) # 42

var.set('spam')

def main():
  print('inside', var.get()) # inside spam
  var.set('ham')
  print('inside', var.get()) # inside ham


ctx = contextvars.copy_context()
ctx.run(main)
print('outside', var.get()) # outside spam

[PEP-545] Python Documentation Translations

 Pythonドキュメントの翻訳に日本語、フランス語、韓国語が追加されました。

 今後中国語などの追加も検討しているようです。

ドキュメントのサポート言語

  • English
  • French
  • Japanese
  • Korean

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:EuroPythonレポート

著者プロフィール

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5