大家好, レアキャラです。 今日はPython3.7の新機能 で気になってるやつを紹介したいと思います。
TL;DR
version | |
---|---|
Python | 3.6.4, 3.7b2 |
mypy | 0.580 |
Python3.7で __future__
に annotations
ってのが追加されて、TypeHintの痒いところに手が届くようになる。
PEP 563 -- Postponed Evaluation of Annotations | Python.org
Python 3.7での変更点
ドキュメントにも書いてあるんですが、軽くコードで書くと
What’s New In Python 3.7 — Python 3.8.0a0 documentation
class C: @classmethod def from_string(cls, source: str) -> C: # クラス内で自分自身のクラス(この場合 `C`)が使えるように ... def validate_b(self, obj: B) -> bool: # クラスBが定義される前でも使えるように ... class B: ...
class
だとこんな感じで結構制約があったのが変更されるようになります。
一個例を上げときます。例えばこんな感じのコードです。
# -*- coding: utf-8 -*- class Meter: def __init__(self, value: int) -> None: self.value = value def add(self, other:Meter) -> None: # Python3.6だと実行時にここがエラーになる self.value += other.value a = Meter(1) b = Meter(2) a.add(b) print(a.value)
$ python3.6 add.py Traceback (most recent call last): File "add.py", line 5, in <module> class Meter: File "add.py", line 8, in Meter def add(self, other:Meter) -> None: NameError: name 'Meter' is not defined
このコードは Python3.6では、実行時エラーになります。クラス内で自分のクラスがTypeHints として使えないからです。(1)
3.7ではこれがfrom __future__ import annotations
を使うことで動かせるようになります。
# -*- coding: utf-8 -*- # from __future__ import annotations class Meter: def __init__(self, value: int) -> None: self.value = value def add(self, other:Meter) -> None: self.value += other.value a = Meter(1) b = Meter(2) a.add(b) print(a.value)
$ python3.7 add.py 3
futureをつけないとPython3.6と同じで実行時エラーになります.これは互換性に配慮した変更です。
ちなみにこれは Python4.0でデフォルトの挙動になります。
Python3系で future
が増えるのは久しぶりです。直感的にわかりやすくかけるので個人的にはなかなかいい変更ダナーと思います。
-
ちなみに
mypy(0.580)
ではこれがエラーになりません。実装系ごとの違いなのかもです↩