Pythonのmarshalモジュールで内部オブジェクトをシリアライズする方法
Python標準ライブラリのmarshalモジュールは、pickleモジュールと同様にオブジェクトのシリアライズ(直列化)機能を提供します。しかし、一般的なデータ永続化やソケット経由でのPythonオブジェクト送受信といった用途にはあまり向いていません。
このモジュールが主に使われるのは、Python自身によるコンパイル済みPythonモジュール(.pycファイル)の読み書き処理です。実は、marshalモジュールが使用するデータ形式はPythonのバージョン間(マイナーバージョン間でさえも)互換性がないため、あるバージョンでコンパイルされたPythonスクリプト(.pycファイル)は、別のバージョンではほとんどの場合実行できません。つまり、marshalモジュールはPythonの内部オブジェクトシリアライズ専用のモジュールだと言えます。
marshalモジュールの主な関数
pickleモジュールと同様に、marshalモジュールにもファイルからシリアライズ済みオブジェクトを読み書きするためのload()およびdump()関数が定義されています。また、文字列(バイト列)として扱うためのloads()とdumps()関数も用意されています。
dumps()関数
dumps()は、Pythonオブジェクトをマーシャリングしてバイト列のようなオブジェクトとして返します。マーシャリングできるのは標準データ型のオブジェクトのみです。サポートされていない型を渡すとValueError例外が発生します。
loads()関数
loads()は、バイト列のようなオブジェクトを対応するPythonオブジェクトに変換します。変換結果が有効なPythonオブジェクトにならない場合、ValueErrorまたはTypeErrorが発生することがあります。
dumps()とloads()の使用例
次のコードでは、Pythonの辞書オブジェクトをdumps()でマーシャリングし、そのバイト表現をloads()で元の辞書に復元しています。
import marshal
person = {"name":"xyz", "age":22, "marks":[45,56,78]}
data = marshal.dumps(person)
obj = marshal.loads(data)
print (obj)ファイルへの読み書き:dump()とload()
dump()関数
dump()は、サポート対象のPythonオブジェクトのバイト表現をファイルに書き込みます。ファイル自体は書き込み権限を持つバイナリファイルである必要があります。
load()関数
load()は、バイナリファイルからバイトデータを読み取り、Pythonオブジェクトに変換します。
.pycファイルの処理にmarshalを使う
前述のとおり、marshalモジュールは.pycファイルの処理に利用されます。次の例では、プリコンパイル済みPythonモジュールの保存に使われるコードオブジェクトに対して、dump()とload()を使用する方法を示しています。
まず、組み込みのcompile()関数を使って、Pythonの命令を埋め込んだソース文字列からコードオブジェクトを作成します。
compile(source, file, mode)
- fileパラメータには、コードの読み出し元となったファイル名を指定します。ファイルから読み込んでいない場合は任意の文字列を渡して構いません。
- modeパラメータは、ソースが一連のステートメントを含む場合は「exec」、単一の式の場合は「eval」、対話的な単一ステートメントの場合は「single」を指定します。
作成したコードオブジェクトは、dump()関数を使って.pycファイルに保存できます。
import marshal
script = """
a = 10
b = 20
print ('addition = ',a+b)
"""
code = compile(script, "script", "exec")
f = open("a.pyc","wb")
marshal.dump(code, f)
f.close().pycファイルからオブジェクトをデシリアライズ(復元)するには、load()関数を使用します。戻り値はコードオブジェクトなので、別の組み込み関数であるexec()を使って実行できます。
import marshal
f = open("a.pyc","rb")
data = marshal.load(f)
exec (data)実行結果は、ソース文字列内に埋め込まれたコードブロックの出力になります。
addition = 30
-
Pythonの内部動作を解説:インタプリタとメモリ上のオブジェクト配置の仕組み
本記事では、Pythonの内部動作について詳しく解説し、Pythonインタプリタがさまざまなオブジェクトに対してどのようにメモリ上の領域を割り当てているのかを見ていきます。 Pythonはどのような言語か Pythonは、Javaと同じくオブジェクト指向のプログラミング言語です。インタプリタを使ってコードを実行するため、「インタプリタ型言語」と呼ばれています。Pythonはミニマリズムとモジュール性を重視する設計思想を持っており、コードの可読性を高めながら、処理時間とメモリ使用量(時間計算量・空間計算量)を最小限に抑えることを目指しています。 また、Pythonの標準的な実装は「CPytho
-
Pythonリストの内部動作を徹底解説!オブジェクトとフレームの仕組み
このチュートリアルでは、Python 3.x(およびそれ以前のバージョン)におけるリストの内部動作について詳しく解説します。Pythonのステートメントを1行ずつ実行したときに、メモリ上でどのようにオブジェクトやフレームが形成されるのかを、図解を交えながら見ていきましょう。 リストの初期化 まずはリストの初期化です。これは、いくつかの要素を持つリストを作成することを意味します。 >>> lis=[1,2,3,4] 上図のように、リスト変数 lis はグローバルフレーム内で宣言され、リストオブジェクトへの参照(ポインタ)を保持しています。重要なのは、変数そのものがデータを格納