1

したがって、拡張機能を作成するための python docs には次のように書かれています。

「インスタンス変数を属性として公開したいと考えています。それを行う方法はいくつかあります。最も簡単な方法は、メンバー定義を定義することです。

static PyMemberDef Noddy_members[] = {
    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
     "first name"},
    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
     "last name"},
    {"number", T_INT, offsetof(Noddy, number), 0,
     "noddy number"},
    {NULL}  /* Sentinel */
};

そして定義を tp_members スロットに入れます:

Noddy_members,             /* tp_members */"

ただし、すでにインスタンス変数を Noddy 構造体に入れています。

 typedef struct {
    PyObject_HEAD
    PyObject *first;
    PyObject *last;
    int number;
} Noddy;

私の質問は、なぜそれらを両方の場所に置くのかということです。私の印象は、インスタンスが更新されたときに型の値を保持するために、型とインスタンスの両方にそれらを持たせたいからです。しかし、その場合、class 属性を変更するとインスタンス値はどのように更新されるのでしょうか? このような:

>>> class foo(object): x = 4
...
>>> f = foo()
>>> f.x
4
>>> foo.x = 5
>>> f.x
5
4

2 に答える 2

3

C拡張機能の記述は複雑なプロセスです。これは、Cコードを記述し、PythonデータをPythonデータであるかのように操作できるようにPythonに十分な情報を提供する必要があるためです。構造体のメンバーについて2回言及する必要があります。1回目はCコンパイラが構造体の作成方法を認識し、もう1回はPythonがデータの場所とその名前を認識できるようにします。

Cにはイントロスペクション機能がないため、たとえば、実行時に構造体のメンバーのリストを取得することはできません。PyMemberDefの配列は、その情報を提供します。

于 2011-06-30T19:43:03.313 に答える
1

わかりましたので、私は調査を行いました。はい、インスタンス変数と属性は異なります。これは、クラスのインスタンスとクラスが別々の辞書を持っているためです。ドキュメントで述べたように::

クラス インスタンスは、クラス オブジェクトを呼び出すことによって作成されます (上記を参照)。クラス インスタンスには、属性参照が検索される最初の場所であるディクショナリとして実装された名前空間があります。そこに属性が見つからず、インスタンスのクラスにその名前の属性がある場合、検索はクラス属性で続行されます。

したがって、基本的に Noddy 構造体はインスタンス変数を保持します。Noddy_members は属性を保持します。さらに:

属性の割り当てと削除は、クラスの辞書ではなく、インスタンスの辞書を更新します。クラスにsetattr () または delattr () メソッドがある場合、インスタンス ディクショナリを直接更新する代わりに、これが呼び出されます。

また:

関連するクラスが、属性参照が開始されたインスタンスのクラス (C と呼ぶ) またはそのベースの 1 つである、ユーザー定義関数オブジェクトまたはバインドされていないユーザー定義メソッド オブジェクトであるクラス属性が見つかった場合、それは、 im_class 属性が C で im_self 属性がインスタンスである、バインドされたユーザー定義メソッド オブジェクトに変換されます。静的メソッドおよびクラス メソッド オブジェクトも、クラス C から取得されたかのように変換されます。上記の「クラス」を参照してください。インスタンスを介して取得されたクラスの属性が、クラスのdictに実際に格納されているオブジェクトと異なる可能性がある別の方法については、記述子の実装のセクションを参照してください。クラス属性が見つからず、オブジェクトのクラスにgetattrがある場合() メソッド。ルックアップを満たすために呼び出されます。

于 2011-07-06T21:21:33.620 に答える