もちろん、reprからオブジェクトを取得する方法はありません。これは、どのクラスもreprで必要なものを返すことができるためです。しかし、reprにポインターが含まれている特定のケースでは、基本的に、ポインターからオブジェクトを取得する方法を尋ねています。これは(少なくともC Pythonでは)IDからオブジェクトを取得する方法を尋ねるのとまったく同じです。
非常に簡単ですが、これを行うための組み込みの方法はありません。これはほとんどの場合悪い考えであるため、これは意図的なものです。
IDでオブジェクトを取得する実用的な目的があると思われる場合は、おそらく間違っています。特に、通常は自動的に処理されるオブジェクトのライフサイクルの問題に対処する必要があるため(そして、背後で、試行しても手動で処理するのが困難になります)。たとえば、オブジェクトがなくなると、そのオブジェクトへのweakrefは無効になりますが、IDは、割り当て解除されたメモリ、後で作成された別のオブジェクト、または1つのオブジェクトの半分と別のオブジェクトの半分を指します。そしてもちろん、C Pythonで行うことは、PyPy、jython、IronPythonでは機能しません…</ p>
しかし、C Pythonランタイムがどのように機能するかをいじくり回しているだけの場合、これは正当な質問であり、正当な答えがあります。おそらくそれを行うための最良の方法は、C拡張モジュールを作成することです。拡張モジュールの作成方法がわからない場合は、最初にそれを学び、後でこの質問に戻る必要があります。そうした場合、実装したい関数は非常に単純です。
static PyObject *objectFromId(PyObject *self, PyObject *args) {
PyObject *obj;
if (!PyArg_ParseTuple(args, "n", &obj)) return NULL;
Py_INCREF(obj);
return obj;
}
必要に応じて、Cの代わりにPyrex/Cythonでこれを行うことができます。または、_ctypesモジュールで直接PyObj_FromPtrを呼び出すこともできます。しかし、このレベルで物事がどのように機能するかを学習しようとしている場合は、何が起こっているのかを明示的にし、「Cポインターの処理」コードをCに明示的に配置する方が理にかなっています。
さらに考えてみると、いじくり回す目的で、ある種の最良のobjectFromReprを構築したかったのです。基本的に:
- 一般的な山かっこ形式に一致する正規表現を使用します。一致する場合は、アドレスを使用してobjectFromIdを呼び出します。
- evalを呼び出します。
そこに中間ステップを入れたいと思うかもしれません。多くのタイプでは、reprはClass(arg1、arg2)のようなコンストラクター呼び出しの形式であり、その場合、その形式を別の正規表現と一致させて呼び出す方がよい場合があります。 evalを使用する代わりに、コンストラクターを直接。他に何もないとしても、それはおそらくより有益であり、それがこの演習のポイントですよね?
明らかに、これはobjectFromIdよりも実際のコードではさらにひどい考えです。ほとんどの場合、evalを使用するのは悪いことであり、eval(repr(x))== xが実際に真であるとは限りません。実際には、idの場合は同じオブジェクトへの新しい参照を取得しますが、 evalの場合も同じ値で、…</ p>
PS、これらすべてがC Pythonでどのように機能するかを学んだ後、jythonやIronPythonなどの別のインタープリターで同様の演習を行う価値があります(特にネイティブJava / .NET / etc。オブジェクトを再現する場合)。