Python3を書いている

ここ最近趣味で作っているツールの開発にPythonを使っている。Pythonの知識は4年以上前に仕事で2.7のスクリプトを書いていた頃で止まっていたんだけど、今回は個人開発だし一気に3.6へジャンプして色々新機能を試しながらコードを書くことにした。

今回はこの開発中に行った環境構築とか、使ってみて良いと感じたPython3の機能についてまとめる。

開発ツール

PyCharmを使うようにした。今では無償で利用できるCommunity Editionが出てるので、自分のようにちょっとした趣味でPythonを書くライトユーザでもPyCharm一択じゃないかと。

最初Emacsで書き始めるためにあれこれ設定を書いていたんだけど、やっぱりIDEインストールしてサッと書き始められる方がいい。PyCharmはキーバインド以外一切カスタマイズ無しで満足に開発できている。

Interpreter

HomebrewでPython3をインストールする。そういえば、まさにこれを書いている最中に色々とゴタゴタが話題になっていたようですね。 (参考:Homebrewでインストールされる/usr/local/bin/pythonが再びPython2に変更)

てっきり brew install python すると2.7が入るものだと思っていたので、インストールは普通にpython3 formulaを指定した。

$ brew install python3
$ python3 -V
Python 3.6.4

次に開発ディレクトリ用にパッケージのインストール空間を独立させる。Python3.3からはvirtualenv相当のvenvというのが標準で組み込まれているので、 python3 -m venv ./venv とするだけで仮想空間を作ることができる。pythonpip 等の実行ファイルも venv/bin 下に入り、PyCharmだと自動でこれを使用するinterpreterとして認識してくれる。

f:id:horimislime:20180312193829p:plain

自分の場合ソースディレクトリはGitでバージョン管理しつつ、iCloudで同期しているDesktop下に置いて複数端末で共有してる。venvも丸ごと同期してあると、開発端末が変わっても全く同じインタプリタとパッケージをすぐに使い始められて便利だった。

Python3以降で良いと感じた仕様

次に、実際にコードを書いていて重宝した新機能を抜粋。

文字化けしなくなった

Python初心者が真っ先にハマると思われるアレが無くなってた。Python3からはUTF-8がデフォルトのencodingになっており、ファイル行頭の coding: utf-8 記述も不要に。

文字列フォーマット

昔は文字列formattingに print 'hello %s' % nameみたいなことをしていたが、3.6からより直感的に書けるようになった。IDEを使っていればブラケット内で変数のメソッドを呼ぶ際補完も効く。

name = 'horimislime'
print('Hello {name.upper()}') # 'Hello HORIMISLIME'

Enum

3.4.1からEnumが標準で使える。classなので勿論メソッドも生やせて便利。

from enum import Enum

class HTTPMethod(Enum):
    Get = 'GET'
    Post = 'POST'
      ...

    def description(self):
        if self == HTTPMethod.Get:
            return '...'
        elif self == HTTPMethod.Post:
            ...

Pythonにはswitchが無いけれど、enumがあるとつい欲しくなってしまう。

async/await

非同期処理をasync/awaitで書けるようになった。promiseライクなことをやりたい時も簡潔に記述できる。

async def update():
    await execute_first()
    await execute_second()


async def execute_first():
    time.sleep(3)
    print('first operation')


async def execute_second():
    time.sleep(1)
    print('second operation')


asyncio.get_event_loop().run_until_complete(update())

Type Hinting

変数に型アノテーションを付けられるようになった。例えば以下のように関数を書いているとき引数に対して補完が効くようになり開発効率が上がった。

def greeting_message(name: str) -> str:
    return f'hello {name.upper()}' # nameに対して補完が効く

型を指定できるようになったので、型がマッチしない代入にも気づける事を期待してたんだけど、これに関しては少しPyCharmのサポートが弱かった。関数に渡す引数の型が合っていないと警告を出してくれるんだけど、以下のような変数への代入では警告が出ない。

def greeting_message(name: str) -> str:
    return f'hello {name.upper()}'

message = greeting_message(name=1234) # 引数にwarning
x: int = greeting_message(name='horimislime') # warningなし

これに関しては python/mypyでチェックをかけると検出できるらしい。ただPyCharmで使うには今のところ手動でmypyを実行するしかなさそうなので、今後のインテグレーション強化に期待。

以上

What’s New in Python — Python 3.6.4 ドキュメントなどを眺めながらここ半月くらいPythonを書いてきた。

元々ヘビーに書いていた訳ではないので、だいぶ初心者に近い視点でPython3を見ていると思う。けれどencoding周りの変更だったり、はじめの環境セットアップのややこしさ(pyenv・virtualenv・virtualenvwrapper…等のツールの乱立)が公式moduleの登場でシンプルになったりと、これからPythonを書き始める人にとっても嬉しい改善が多い気がする。

最近ずっとSwiftを書いていたのでだいぶモダン寄りな言語から入ってきた形になったけど、こうした環境面の改善だったり言語仕様のパワーアップでそんなに戸惑うこともなかった。むしろasync/awaitはSwiftでも使えると便利だなと思ったりもした。