[小ネタ] Pythonでimportの前に関数を実行しなければならないときの苦肉の策

  • 3
    いいね
  • 0
    コメント

小ネタです。
殆どないケースですが、Pythonでimportの前に関数やメソッドの実行をする要件が出てきたときの策です。

経緯

LinuxでmatplotlibをインストールしてPythonコード上で使用した時に以下のようなエラーが発生しました。

_tkinter.TclError: no display name and no $DISPLAY environment variable

このエラーの解決策は検索するとすぐに出てきて、matplotlibのバックエンドをAggにすればいいというのが回答のようです。(エラーやバックエンドについての詳細は今回は割愛します)

その方法はいくつかあるようで、/etc/matplotlibrcにbackend: Aggと記載する方法1と、matplotlib.use('Agg')を使用する方法2 が検索上位に上がっていました。

今回はそのうちmatplotlib.use('Agg')を採用するとします。

問題点

import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot


def plot(data):
    pyplot.plot(data)

上記のようにimportした後にmatplotlibu.use('Agg')を呼べば動くのですが、これには問題があって、import順を自動で変更するツール(isortなど)を導入していると以下のように書き換えられてしまいます。

import matplotlib
from matplotlib import pyplot

matplotlib.use('Agg')


def plot(data):
    pyplot.plot(data)

matplotlib.use('Agg')from matplotlib import pyplotを書く前にを呼ばなければいけないようで、CIで自動的にコードをチェックする場合などは困ってしまいます。実行時に呼び出し元関数の中でimportするという手も一応はありますが、importする数や関数の数が増えた場合にだんだん煩雑になっていきます。

対策

対策として以下のように実装できます。

try:
    import matplotlib
    matplotlib.use('Agg')
finally:
    from matplotlib import pyplot


def plot(data):
    pyplot.plot(data)

一応はこれで順序の保証ができます。