PythonでIDを取得してオブジェクトに戻す

TL;DR

PythonでIDを取得してオブジェクトに戻す小技の紹介です.

IDを取得する

Pythonではid関数を使うことでオブジェクトのIDを取得することができます.
これはオブジェクトを一意に表すIDです.

>>> val = 5
>>> id(val)
140725152520080

型にもあります
>>> val = int
>>> id(val)
140725152283920

オブジェクトに戻す

一意に表すIDであればIDからオブジェクトを取得できるのでは?という話です.

_ctypesモジュールのPyObj_FromPtrという関数を使用します.

>>> import _ctypes
>>> val = 5
>>> id(val)
140725152520080
>>> _ctypes.PyObj_FromPtr(140725152520080)
5

インスタンスオブジェクトでも.

>>> import _ctypes
>>> class Test:
...     def __init__(self, val):
...             self.val = val
...
>>> test = Test(10)
>>> test.val
10
>>> id(test)
2441514736128
>>> test_from_id = _ctypes.PyObj_FromPtr(2441514736128)
>>> test_from_id.val
10

使い道

マルチプロセスを使う際,プロセス間通信の引数はシリアライズ可能である必要があります.
インスタンスオブジェクトを渡す際は引っかかることが多いかと思います.
id関数と_ctypes.PyObj_FromPtrを使うことで,IDだけ渡して,渡した先で復元するということができます.

また,IDの値はint値なのでオブジェクトの代わりに保持しておく,ということができます.
(ポインタなので変わらんじゃんという話もありますが...)

懸念

スコープなのか呼び出し階層なのかは分かりませんが,IDの値が別のオブジェクトになっていることもあります.
なるべく同じスコープ,短い呼び出し階層で使うことをお勧めします.

まとめ

Pythonにはこういったメタ関数が多くあるので面白いですよね.
ご参考になれば幸いです.

シェアする

  • このエントリーをはてなブックマークに追加

フォローする