1.はじめに
python3.7で増えた機能の主要なところを実際に使って見たまとめ.
全体についてはこの辺が良い.->Python3.7の新機能
2.environment
- python 3.7.0(pyenvで入れる)
3.install
pyenvを更新したら3.7.0もインストール可能なリストに出てくる.
$ git clone git://github.com/yyuu/pyenv-update.git ~/.pyenv/plugins/pyenv-update
$ pyenv update
$ pyenv install -list
Available versions:
3.7.0
3.7-dev
3.8-dev
4.dataclasses
4.1.dataclassの何が嬉しいか
dataclassは自分用のデータ型の定義の新しいやり方.
@dataclass
でデコレートするようにして使う.
そうすると,@dataclass(order=True)
というように引数のbool値を変えるだけで,そのクラスの特殊メソッドを生やすことができる.
具体的には以下のような感じ.
from dataclasses import dataclass
from dataclasses import field
from typing import List
@dataclass(init=True, order=True)
class HyperParams():
init_val: float = field(default_factory=float, compare=True)
iter_num: int = field(default_factory=int, compare=True)
tol: float = field(default_factory=float, compare=True)
logging: List[int] = field(default_factory=list, compare=False)
order=True
とすると,比較演算子が使えるようになる.
field
のcompare=True
で比較演算子を用いた時のその変数を比較対象にするか否かを選べる.
logging
はcompare=False
で比較対象から抜いている.
params1 = HyperParams(10, 20, 30, 10)
params2 = HyperParams(500, 200, 300, 100)
params1 <= params2
# True
4.2.dataclassを使わずに書くと
ちなみにこのorder=True
で__le__
の特殊メソッドを生やしていて,これによって比較演算子<=
が使えるようになる.dataclassを使わずに書くと以下のようになる.
class HyperParams_oldstyle(object):
def __init__(self, init_val: float, iter_num: int, tol: float, logging: list):
self.init_val = init_val
self.iter_num = iter_num
self.tol = tol
self.logging = logging
def __le__(self, other):
if other.__class__ is self.__class__:
return (self.init_val, self.iter_num, self.tol) <= (other.init_val, other.iter_num, other.tol)
params_old1 = HyperParams_oldstyle(10, 20, 30, 10)
params_old2 = HyperParams_oldstyle(500, 200, 300, 100)
params_old1 <= params_old2
# True
こう比べると確かに引数のTrue, False
だけで色々いじれるdataclass便利そうと思える.
4.3.その他の機能
あとfrozen=True
で変更不可になる.これも時々使いそう.
@dataclass(frozen=True)
他の機能についてはこの辺が参考になりそう.
Python3.7からは「Data Classes」がクラス定義のスタンダードになるかもしれない
4.4.参考
5.breakpoint
5.1.breakpointの何が嬉しいか
コードの途中でpbdモードに入る.
built-inに入っているので,わざわざpbd
をimportしなくてもよくなった.
for
文の途中でも入れるので1ステップずつ挙動を確認したいときとかに便利そう.
i_list = []
for i in range(10):
i_list.append(i)
breakpoint()
>>> i_list = []
>>> for i in range(10):
... i_list.append(i)
... breakpoint()
...
> <stdin>(1)<module>()
(Pdb) i_list
[0]
(Pdb) continue
# continueでまたbreakpoint()から再度実行.
> <stdin>(1)<module>()
(Pdb) i_list
[0, 1]
(Pdb) continue
> <stdin>(1)<module>()
(Pdb) i_list
[0, 1, 2]
5.2.参考
-
Python 3.7’s new builtin breakpoint — a quick tour – Hacker Noon
- コマンドラインからの実行時にbreakpointのskipもできるようだ.