Python
Python3

Python3.8の新機能 (まとめ)


はじめに

Python 3.5から What's Newの内容をまとめる記事を投稿してきました。

Python 3.8も開発ロードマップができてそろそろアルファ版が出てくるタイミングなので変更点についてまとめていこうかと思います。

最初はなかなか普及の進まなかったPython3も版を重ねてついに 3.8で、2.7で打ち止めになったPython2をこれでマイナーバージョン数でも越えることになります。利用者数も少し前のこの記事によると75%がPython3になっているみたいですし、名実ともにメインストリームにようやくなったという感じでしょうか。Python2のメンテナンスも今年いっぱい(PEP-373)なので今年は更にPython3への移行が加速するでしょう。

なお、これまではWhat's Newの内容を網羅的にカバーしていましたが、レベルの違う変更点が羅列されて長くなるし、こちらも更新内容を追いかけるのが辛くなってくるので、個人的な視点で興味を持った部分を中心に書いていこうかなと思います。

そして書き始めて気がついたけど、取り上げる機能の数が減っても一つ一つに関して詳しく書いていくとあっという間に長くなってしまう。なので、長くなったものに関しては別記事に分離しこちらにはそれへのリンク + 小変更の紹介を書いていこうかと思います。

で、何はともあれ、開発ロードマップ(PEP-569)。


  • 3.8 開発開始: 2018-01-29 (完了)

  • 3.8.0 alpha 1: 2019-01-27 -> 2019-02-04 (完了)

  • 3.8.0 alpha 2: 2019-02-24

  • 3.8.0 alpha 3: 2019-03-24

  • 3.8.0 alpha 4: 2019-04-28

  • 3.8.0 beta 1: 2019-05-26 (これ以降は新機能の追加なし)

  • 3.8.0 beta 2: 2019-06-23

  • 3.8.0 beta 3: 2019-07-28

  • 3.8.0 beta 4: 2019-08-25

  • 3.8.0 candidate 1: 2019-09-29

  • 3.8.0 candidate 2: 2019-10-06 (必要であれば)

  • 3.8.0 final: 2019-10-20

予定通りに行って、あと10ヶ月! 長いですができるだけこまめに追いかけて行きたいと思います。


更新履歴


2019.02.05

3.8.0a1がリリースされました(リリースアナウンスメント)。代入式の導入に関する記事へのリンクを追加しました。


2019.01.20

最初のバージョン。またa1が出ていないタイミングで書いています。


注目した新機能


代入式の導入

→ 別記事にしました: Python3.8の新機能(2) - 代入式の導入


コンパイルしたバイトコードファイルの置き場所を指定できる

→ 別記事にしました: Python3.8の新機能(1) - コンパイルしたバイトコードファイルの置き場所を指定できる


その他の言語の変更


finallyの中でcontinueが使えるようになる

これまでは

while True:

try:
pass
finally:
continue

というのを実行しようとすると

SyntaxError: 'continue' not supported inside 'finally' clause

というエラーが出ていました。実装上の都合でそうなっていたらしいのですが、3.8からはその制約が外れます。が、実質的にこれが必要なケースが思いつかない...


int型にas_integer_ratio()メソッド追加

これまでfloat型にはas_integer_ratio()というメソッドがあり、

>>> (3.5).as_integer_ratio()

(7, 2)

と浮動小数点数をf = a/bが成り立つ2つの整数のペアを返してくれます。このメソッドをint型にも導入するということですが、(i, 1)を返すだけのようです。一見意味がなさそうですが、mypyのような静的型付拡張されたPythonでfloat型とのint型を統一的に扱うためにこれが必要とのこと。


辞書型(dict)でreversedが使えるようになった

3.7で辞書型の順序保証がされるようになった(入力順に並ぶ)ので当然の帰結ですが、辞書型でreversed()が使えるようになりました。逆に3.7でなぜ実現されなかったのかが不思議ですが、これまでは TypeError: 'dict' object is not reversibleというエラーが出ていました。3.8ではこんな感じで普通に使えます。

>>> d = {'a': 1, 'b': 2}

>>> print(list(reversed(d)))
['b', 'a']


モジュールの改善


json.tool

個人的には結構良いなと思った拡張です。

jsonを見やすく表示するツールとしてjqなどがありますが、自分としてよく使うのが、python -m json.tool < <jsonfile>。でもこれは入力が一つのjsonオブジェクトであることを想定しているので、複数のjsonオブジェクトを含むファイルを入力すると2つ目の頭を呼んだところでエラーになります。

それが、3.8から--json-linesというオプションが導入され、1行に1 jsonオブジェクトというフォーマットであれば読めるようになりました。

例えばこのようなjsonファイルが有る場合

{"city": "tokyo", "temperature": 6}

{"city": "osaka", "temperature": 5}
{"city": "taipei", "temperature": 17}

3.7 ではエラーになります。

$ python -m json.tool < a.json

Extra data: line 2 column 1 (char 36)

一方で3.8ではこのようになります。

$ python -m json.tool --json-lines < a.json

{
"city": "tokyo",
"temperature": 6
}
{
"city": "osaka",
"temperature": 5
}
{
"city": "taipei",
"temperature": 17
}

願わくば、jqみたいに1行 1jsonではなくても複数オブジェクトを読んでくれれば良いのになと思うのですが、それはそれできっと問題があるのでしょう。


最適化


ファイル・ディレクトリコピーの高速化

shutil.copyfile(), shutil.copy(), shutil.copy2(), shutil.copytree() shutil.move()がそれぞれのプラットフォームで最適なシステムコールを使って実現される様になったとのこと。結果として、Linuxで26%、 macOSで50%, Windowsで40%速くなったとの計測結果も出ているらしいです。


まとめ

Python 3.8の変更点についてまとめてみました。これからドンドン追加されていくはずなので、頑張って追いかけます。