0

重複の可能性:
Python: ID でオブジェクトを取得する

通常、インスタンスの文字列表現を見ると、次のようになり<module.space.Class @ 0x108181bc>ます。この文字列を取得してインスタンスのハンドルを取得できるかどうかに興味があります。

何かのようなもの

 obj_instance = get_instance_form_repr("<module.space.Class @ 0x1aa031b>")

私はそれが可能であるとは思わないが、もしそうなら、それは本当に役に立つだろう.

4

2 に答える 2

2

少なくともガベージ コレクターによって追跡されるサブセットに対しては、厄介で信頼性の低い方法で実行できます。

def lookup_object_by_repr(myrep)
    import gc
    for obj in gc.get_objects():
        if repr(obj) == myrep:
           return obj

単純な C 拡張機能を作成してメモリ アドレスを調べると、さらに多くのことができます。

于 2012-06-13T19:07:00.503 に答える
1

もちろん、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。オブジェクトを再現する場合)。

于 2012-06-13T17:47:27.203 に答える