2011-06-30 9 views
1

だから、writing extensionのためのPythonのドキュメントは、この言う:。Pythonのインスタンス変数と属性の違い?

は、「我々は、属性として、当社のインスタンス 変数を公開することを行う方法の 多数あり 最も簡単な方法は、メンバー を定義することです。定義:

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; 

をので、私の質問は、なぜ我々は両方の場所に入れていることです。私の印象は、型とインスタンスの両方にそれらを持たせて、インスタンスが更新されると型の値を保持したいからです。しかし、その場合、クラス属性を変更した場合、インスタンス値はどのように更新されますか?あなたがCのコードを記述する必要があり、そしてあなたはそれがPythonのデータであるかのように、それはあなたのCのデータを操作できるように、Pythonのに十分な情報を提供する必要があるため、C拡張を書く

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

答えて

1

私は研究を行いました。はい、インスタンス変数と属性は異なります。クラスインスタンスとクラスには別々の辞書があるためです。 documentationに述べたように::

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

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

属性の割り当てや削除は、インスタンスの辞書、 決してクラスの辞書を更新 。 クラスに(setattr()または delattr()メソッドがある場合は、インスタンス 辞書を直接更新する代わりに呼び出されます。また

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

2

は、複雑なプロセスである。このような。構造体のメンバについては、Cコンパイラが構造体の作り方を知っていることを理解してから、もう一度Pythonがデータの場所と呼び出し先を知るようにしてください。

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

+1

Pythonには、Cソースコードを調べ、 'struct'のメンバーの名前と型を見ることはできません。その情報は通常、コンパイルされたコードには存在しないので、Pythonがそこにアクセスできるようにする必要があります。 – kindall

関連する問題