Pythonのすべてのクラスは、クラス「オブジェクト」から継承します。'object'クラス実装の内部メカニズムについて疑問に思っています。'object'クラスにユーザー属性を割り当てることができないのはなぜですか?これはメモリ管理に関連していると確信していますが、ユーザーが自分でメモリ管理を実装することを考えている場合、Pythonで「object」クラスをオーバーライドできないのはなぜですか?これは私の興味に基づいており、プログラムによるアプリケーションがない可能性があるものについて知りたいのですが、言語自体の内部機能を知っておくと便利です。
3 に答える
Cで定義されたタイプは、ユーザーが割り当てた属性を持つことはできません。グローバルに置き換える場合objectは、存在するすべてのクラスを反復処理して__builtin__.objectから、将来のすべてのクラス作成をキャッチするために置き換える必要があります。そして、古いオブジェクトが別の場所にバインドされる可能性があるため、それでも信頼できません。
これはStackOverflowで議論されていますが、それをリンクするための議論を見つけるのに苦労しています。
私が疑問に思った理由は、この例を単純化したかったからです。
class Box(object):
pass
box = Box()
box.a = "some value"
box.b = 42
ここでboxは、キーが識別子のみである辞書の一種として使用しています。box.aこれを行うのは、よりも書く方が便利だからですbox["a"]。
私はこれをやりたかった:
box = object()
box.a = "some value" # doesn't work
その理由はobject、Pythonのすべてのオブジェクトのルートであるためです。持つすべての属性objectは、任意の派生型である必要があります。多数のオブジェクトを含む大きなリストを作成する場合は、メモリが不足しないように、オブジェクトをできるだけ小さくする必要があります。したがって、objectそれ自体は最小限です。
編集:私が覚えようとしていたリンクを見つけました:
__slots__第一原理から推論を導き出さなければならないのなら、それをメカニズムの観点から考えるかもしれません。一部の種類のクラスは少数の属性のみを必要とし、属性のセットはすべてのインスタンスに対して常に固定されているため、ユーザー属性機能のような「dict」の柔軟性は、CPU(動的に名前が付けられた属性の検索)とスペース(空のdictのオーバーヘッド、小さいがゼロ以外)。これは、インスタンスが多数ある場合、実際には多くのオーバーヘッドになる可能性があります。
もちろん、これはまさに__slots__メカニズムが解決する問題です。スロットで定義された属性のために、オブジェクトにスペースが割り当てられます。属性がある場合__dict__は、スロット以外の属性がそこにあります__dict__。属性がない場合は、動的属性も、不要なdictオブジェクト(インスタンス自体以外の追加のヒープオブジェクト)のコストも取得されません。
なぜobjectそれ自体にスロットがないのかというと、サブクラスがスロットを必要__dict__としないことを示したとしても、スロットを必要とするクラスから継承する場合、インスタンスにはまだ;が必要です。もし持っていれば、絶対にすべてのクラスは、たとえそれを必要としなかったとしても、持っていることの代償を払うでしょう。__dict____dict__object__dict____dict__
その代わり; サブクラスは、それ自体がクラス属性を定義しない限り、取得します__dict__(そして、同様の理由で)。__weakref____slots__
objectそして、なぜあなたはまったくのプレーンなインスタンスが必要なのでしょうか?属性のバッグが必要ですか?それでは、を使用してdictください。動作と属性を持つある種のオブジェクトが実際に必要な場合は、とにかくサブクラスを作成しています。
object()のサブクラスの代わりに使用することを想像できる唯一の理由はobject、対象となるインスタンスの唯一の機能がそのIDである場合です。これは、関数が引数を取るときに発生します。この場合、Noneまたはその他の明らかな番兵の値は、デフォルトとは異なるものとして理解する必要があります。
BAR_DEFAULT = object()
def foo(bar=BAR_DEFAULT):
if bar is BAR_DEFAULT:
#...
この場合、のインスタンスに属性は必要なく、特に必要でもありませんobject。