皆さんJupyter使ってますか?使ってますよね??
それでは何のJupyter使ってますか?普通のJupyterですか?JupyterLabですか?Google Colaboratoryですか??
これからの時代はJupyter Notebooks in VS Code一択です。今からその理由をご説明します。きっと乗り換えたくなること間違いなし。
class Dog:
bark = "ワン!"
class Cat:
meow = "ニャー!"
animal = Dog() if True else Cat()
animal.name = "ポチ"
setattr(animal, "type", "柴犬")
このコードの実行結果はどうなるでしょうか?
animal.name # 'ポチ'
animal.type # '柴犬'
animal.bark # 'ワン!'
animal.meow # AttributeError: 'Dog' object has no attribute 'meow'
当然ですね。
着目したいのは、VSCodeがこのanimal
という変数をどのように認識しているかです。
動的解析と静的解析
ソースコードを解析し、適切な補完機能を提供するために取られるアプローチは、動的解析と静的解析に大別されます。
dir
関数を思い出してください。
dir(1) # ['__abs__', '__add__', '__and__', ...]
これは動的解析の結果です。IPythonによって取得できるので、例えばGoogle Colaboratoryでも補完結果が表示されます。
これに対し、静的解析では、ソースコード自体の意味を理解して解析します。例えば、下記のコードでは、animal
は99%の確率でDog
ですが、1%の確率でCat
になります。
animal = Dog() if random.random() > 0.99 else Cat()
VSCodeは、この文構造からanimal
をDog | Cat
(Dog
またはCat
である型)と認識します。
このため、VSCodeはbark
とmeow
をともに補完候補として表示させます。動的解析しか行うことのできない他のJupyter Notebook実装ではこの機能を実現することができず、animal
がCat
である可能性を見落としてしまうかもしれません。
VSCodeにこの能力を与えているのは、Microsoftの開発したPylanceです。PylanceはTypeScript(!)で開発されたLanguage Serverで、軽量ながら非常に高度な解析を行うことができます。
動的解析と静的解析には、それぞれメリットとデメリットがあります。一方のメリットが他方のデメリットになる、といった感じですね。
- 動的解析
- 存在するプロパティをすべて確実に表示できる
- 実行してみないと解析できない
- 前提条件によって存在し得るプロパティが異なる場合は当てにならない
- 静的解析
- コードパスを網羅的に検討することができる
- 実行しなくても解析できる
- ソースコードから解析しづらい動的に生成されるプロパティを発見できない
VSCodeのスゴいところ
VSCodeのJupyterが画期的なのは、動的解析と静的解析のいいとこどりができるところです。もう一度最初のコードに戻ってみましょう。
animal = Dog() if True else Cat()
animal.name = "ポチ"
setattr(animal, "type", "柴犬")
このコードを実行した後、animal
のプロパティ候補として何が表示されるでしょうか?
記号の異なるbark
がリストに2回表示されていることにお気付きいただきましたでしょうか?実は、
アイコン | 意味 |
---|---|
静的解析で見つかったプロパティ | |
動的解析で見つかったプロパティ |
のように意味が分かれています。meow
は実際には存在しないけれどもコードパス上は存在し得るため静的解析のみで、name
やtype
は静的解析では存在を発見しづらいので動的解析のみで、bark
はどちらによっても発見し得るので2種類のアイコンが並んでいることになります。
どのように活用するか
多くの場合、コードの静的解析の結果は、実行時のコンテキストに依存する動的解析の結果より信頼性の高いものです。しかしながら、pandas等、読み込んだデータによってプロパティが変わるようなライブラリを用いる場合、静的解析の結果のみでは発見できないプロパティが多く、開発速度が低下してしまうでしょう。
幸いなことに、今日ではPythonでもtype hintingと呼ばれる、型情報を明示的に宣言する機能が使用できるようになりました。例えば、
animal = Dog() if True else Cat()
といったコードでは、人間にとってはanimal
がDog
であることは明らかですが、現在のPylanceの静的解析能力ではこれを判定することができません(ちなみにTypeScriptは理解できます)。上記コードに型注釈をつけると、
animal: Dog = Dog() if True else Cat()
のようになります。この場合、VSCodeではanimal
がDog
であると正しく認識できるようになります。
データの前処理などで、pandas等データをぐちゃぐちゃに変化させるようなライブラリを使用する場合は動的解析に頼り、ある程度前処理が終わってデータ構造がはっきりとしたタイミングで静的解析が可能になるように型注釈をつける、といった運用にすれば、両者のメリットを最大限享受することができるようになるでしょう。それを可能にしてくれるのは、私が知る限りVSCodeのJupyterだけです。
その他の機能
これ以外にも、VSCodeのJupyterは猛烈な進化を遂げていているようです。Microsoftはどこへ向かっているのか・・・。
Live Share
ホストがLive Shareで共有することで、ゲストはホスト側で開かれているプロジェクトをGoogleドライブのように同時に編集することができるようになります。Google Colaboratoryでもできますがそれよりも圧倒的に低レイテンシで使い勝手が良いです。
ただ残念なことに記事執筆時点 (2021/07/10)ではゲスト側で補完は動作しません。通常のPythonファイルでは動作するので、アップデートに期待ですね。
Diff
お馴染みDiffの機能がついにJupyterでも使えるようになりました。右側パネルは普通に編集できますし、動的解析のみですが補完も効きます。すごい。
デバッガ
ついにJupyter Notebookのデバッガも使えるようになるそうなのですが(これまでは一度.pyに変換しないといけなかった)、まだExperimentalだそうで動作しません。早く試したい!