LoginSignup
108
73

More than 3 years have passed since last update.

Jupyter Notebook のグローバル変数汚染との戦い

Last updated at Posted at 2020-12-13

Kaggle Advent Calendar の12日目の記事です。

こんにちは。fkubotaです。今はKaggle Expertです。
さっそくですが、Jupyter Notebook で作業をしている時、グローバル変数に困らされたことはないでしょうか?

僕は業務でもKaggleでもNotebook上で作業をすることが多々あるのですが、結構な頻度で意図しないグローバル変数が原因のバグに出会います。

そこで以下のTweetをしてみました。これが事の始まりです。

こういったこと、クラスとか使ってちゃんと書いた.pyのスクリプトだと起こらない自体ですよね。
Jupyter Notebookは便利ですが、こういったことが原因のバグを埋め込んでしまうことがあります。
これを避けるには、notebookを使わないという選択肢もありますが、もっと簡単な方法で避けることができます。

詳細は省きますがnyker_gotoさんまますさんなどのお力を借りて@noglobals デコレータを使えばいいということで決着します。

簡単な例で説明します。まずは、@noglobals を定義します。

import builtins
import types

def imports():
    for name, val in globals().items():
        # module imports
        if isinstance(val, types.ModuleType):
            yield name, val

            # functions / callables
        if hasattr(val, '__call__'):
            yield name, val


def noglobal(f):
    '''
    ref: https://gist.github.com/raven38/4e4c3c7a179283c441f575d6e375510c
    '''
    return types.FunctionType(f.__code__,
                              dict(imports()),
                              f.__name__,
                              f.__defaults__,
                              f.__closure__
                              )

準備完了 です!!どう使うかというと、デコレートするだけです。

エラーがでない例
image.png

エラーがでる例
image.png

この手軽さがたまりません。現在、notebookで作業しているのであれば、@noglobals を関数に片っ端からつけてみてはいかがでしょうか。

簡単ですが、効果の大きいテクニックかなと思います。

最後に、簡単なサンプルのノートブックと、問題を解決しようとした猛者たちの戦いを紹介して終えようと思います。

  • sample notebook
  • 猛者たちの戦いTweet↓

以上です!快適なJupyter Notebookライフを送りましょう!

108
73
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
108
73