PythonのzipimportモジュールでZIPアーカイブからモジュールをインポートする方法
zipimportモジュールとは
Python標準ライブラリの「zipimport」モジュールを使うと、ZIP形式のアーカイブから直接Pythonモジュールやパッケージをインポートできます。sys.path の要素として、ディレクトリ名ではなくZIPファイル名を文字列で指定することも可能です。
ZIPアーカイブの中には任意のファイルを含められますが、インポート対象になるのは拡張子が .py および .pyc のファイルだけです。なお、C言語などで実装された動的モジュール(.pyd や .so)をZIP経由でインポートすることはできません。
サンプル用のZIPアーカイブを作成する
ここでは、「newdir」ディレクトリ内に次のファイルが存在するものとします。
['guess.py', 'hello.py', 'impzip.py', 'mytest.py', 'prime.py', 'prog.py', 'tmp.py']
まず、zipfileモジュールの PyZipFile クラスを使って、これらの .py ファイルを1つのZIPアーカイブ(zipimp.zip)にまとめます。
import sys, glob
import zipfile
files = glob.glob("*.py")
print(files)
zf = zipfile.PyZipFile('zipimp.zip', mode='w')
for file in files:
zf.write(file)
zf.close()以降の説明では、この「zipimp.zip」を使用していきます。
zipimporterクラスの主なメソッド
zipimportモジュールは zipimporter クラスを定義しており、以下のメソッドが利用できます。
コンストラクタ:zipimporter(path)
新しいzipimporterインスタンスを生成します。引数にはZIPファイルへのパスを指定します。パスが有効なZIPアーカイブでない場合は ZipImportError が発生します。
>>> import zipimport
>>> importer = zipimport.zipimporter('zipimp.zip')find_module(fullname)
指定したモジュールを検索します。見つかった場合はzipimporterインスタンス自身を返し、見つからなければ None を返します。
>>> ret = importer.find_module('prime')
>>> ret
<zipimporter object "zipimp.zip">
>>> ret = importer.find_module('sample')
>>> print(ret)
None※find_module() はPython 3.10で非推奨となり、3.12で削除されました。新しく書くコードでは find_spec() を使用してください。
get_code(fullname)
指定したモジュールのコードオブジェクトを返します。モジュールが見つからない場合は ZipImportError を発生させます。
>>> prog = importer.get_code('prime')
>>> print(prog)
<code object <module> at 0x022A4650, file "zipimp.zip\prime.py", line 1>load_module(fullname)
指定したモジュールを読み込みます。インポートされたモジュールを返し、見つからない場合は ZipImportError を発生させます。
>>> importer = zipimport.zipimporter('zipimp.zip')
>>> mod = importer.load_module('prog')
30
>>> mod.__name__
'prog'
>>> mod.__file__
'zipimp.zip\\prog.py'
>>> mod.__loader__
<zipimporter object "zipimp.zip">get_source(fullname)
指定したモジュールのソースコードを返します。
>>> prog = importer.get_source('prime')
>>> print(prog)
def isprime(x):
for i in range(2,x-1):
if x%i==0:
return False
else:
return True
f = int(input())
l = int(input())
primelist = list(filter(isprime, range(f,l)))
print("prime1", "prime2", "composites")
composites=[(primelist[i-1], primelist[i],(primelist[i]-1)-primelist[i-1]) for i in range(1,len(primelist))]
print(composites)まとめ
zipimportを活用すれば、複数のモジュールを1つのZIPファイルにまとめて配布し、通常のモジュールと同じようにインポートして使えます。sys.path にZIPファイルのパスを追加すれば、import文から透過的に読み込むことも可能です。アプリケーションのパッケージングや配布形態の選択肢として覚えておくと便利でしょう。
-
Pythonモジュールから単一の関数だけをインポートする方法
Pythonでは、from モジュール名 import 関数名 という構文を使うことで、モジュールから特定の関数だけを選んでインポートできます。モジュール全体を読み込む必要がないため、コードが簡潔になり、名前空間もすっきりと保たれます。基本的な使い方たとえば、mathライブラリからsin関数だけをインポートし、他の関数は読み込まないようにしたい場合は、次のように記述します。>>> from math import sin >>> sin(0) 0.0「math.」という接頭辞が不要になる理由この方法でインポートされるのはsin関数のみであり、mathモジュー
-
Pythonで複数のモジュールをインポートする方法まとめ
Pythonで複数のモジュールを読み込みたい場面はよくあります。実は方法はいくつかあり、状況に応じて使い分けることでコードがより読みやすくなります。ここでは代表的な4つの方法を、実際のコード例とあわせて紹介します。 1. import文を複数回書く(基本の方法) 最もシンプルで一般的なのは、import文を必要な回数だけ繰り返し記述する方法です。 >>> import os >>> import math >>> import sys PEP 8(Python公式スタイルガイド)では、このように1行に1つのimport文を書くことが推奨さ