import Image
Image.open('figure.png')
としたところ、"cannot identify image file"と、これまで使えていたスクリプトにもかかわらずエラーが生じました。 'figure.png'が破損でもしたのかと思ったのですが、 ビューアで開くと画像ファイルに問題はありませんでした。
そういえば、最近、reportLabをインストールしたところで、 PIL(Python Imaging Library)としてPillow 4.0.0がインストールされました。 そこで、site-packagesにあるPIL/Image.pyを覗いてみたところ、問題は、 イメージの種類に対応するPluginが正常に登録されていないことでした。
Image.open()を呼び出すと、そこでpreinit()が呼ばれ、 BmpImagePluginやPngImagePluginといった画像の種類に対応したモジュールがimportされます。 それぞれのPluginモジュールは、 Imageモジュール内のregister_open()等の関数を用いて、 Imageモジュールの*トップレベルに作成されたリストや辞書*にID等を登録していきます。
構造としては、ImageモジュールでPluginモジュールをimportして、 Pluginモジュールで、Image.register_open()を呼び出しているわけです。 さて、問題の箇所は、 Imageモジュールの*トップレベルに作成されたリストや辞書*は、 Imageモジュールから見るとglobal変数なのですが、 Pluginモジュールから見るとImageモジュールの変数であり、別物ということです。
以下、確認のためシンプルなスクリプトを4つ用意しました。
#-- module_main.py --
GLOBAL_V =[]
def register(x):
#global GLOBAL_V
GLOBAL_V.append(x)
def importer():
import plugin_100
import plugin_200
if __name__ == '__main__':
importer()
print GLOBAL_V
#-- plugin_100.py -- import module_main module_main.register(100)
#-- plugin_200.py -- import module_main module_main.register(200)
#-- using_module.py -- import module_main module_main.importer() print module_main.GLOBAL_V
module_mainにあるregister()を呼び出して、 module_mainにあるGLOBAL_Vに値を追加していくものです。
module_main.pyを直接実行してみます。
>python module_main.py []
module_main.pyを実行しても、GLOBAL_Vの値は変更されていません。 register()の中にあるglobal GLOBAL_Vがコメントアウトされてているからではありません。 コメントアウトを外して確認できるように、記述しました。
module_mainをimportして利用するusing_module.pyを実行してみます。
>python using_module.py [100, 200]
と、設定されました。 このGLOBAL_Vは、グローバル変数を意図して作成されたものではなく、 モジュール変数を意図して作成されたもののようです。 (だからregister()内に、global GLOBAL_Vがないのですね)
ということで、Import Imageとすると、Image内で参照されているグローバル変数と、 PluginからImage.open_register()の呼び出しで変更される変数が別物(Imageのモジュール変数) になってしまうということでした。
from PIL import Image
Image.open('figure.png')
とすることで、問題は解決しました。
import Imageでエラーが出なかったため、
はまってしまったのでリマインダとして残しておきます。
(エラーがでなかったのは、以前のPILのPIL.pthが残っていたためです。)
PILのimport Imageというimportの方法は、
廃止されるようですね。
問題が分かって検索してみると、
同じようなことが。
0 件のコメント:
コメントを投稿