4

オブジェクトの Python インターピーターはどのようなデータを保存しますか?
たとえば、次のようなコードで:

class MyClass:
    pass

if __name__ == "__main__":
    c = MyClass()
    import sys
    print sys.getsizeof(c),sys.getsizeof(MyClass)

出力が 72 と 104 なのはなぜですか? クラスがオブジェクトインスタンスよりも大きいのはなぜですか? クラスとオブジェクトは、72 文字と 104 文字を占める何を格納する必要がありますか?

驚いたことに、これを実行すると:

class MyClass:
    def __init__(self):
        self.mIntValue = 1024
        self.mStringValue = "hust";

if __name__ == "__main__":
    c = MyClass()
    import sys
    print sys.getsizeof(c),sys.getsizeof(MyClass)

出力はまだ 72 と 104 ですが、2 つのプロパティを追加したので、オブジェクトが「大きく」なるはずです。まあ、結果はそうではないようです。

4

1 に答える 1

7

基本的に、python のクラスとインスタンスはどちらもオブジェクトです。のサイズをテストするときMyClass()は、インスタンス オブジェクトのメモリ サイズを照会していますMyClass。 をテストするときは、クラス オブジェクトのサイズをテストしています。

どちらのオブジェクトにも独自のフィールドがあるため、サイズが異なります。クラス オブジェクトがインスタンスよりも多くのメモリを必要とするのは当然のことです。

Python のクラスのインスタンスは、名前を Python オブジェクト (関数、フィールドなど) に関連付ける一種の辞書です。実際、それらはMyClass().__dict__辞書に格納されています。したがって、クラスにさらにフィールドを追加しても、クラス__dict__はフィールドを格納するオブジェクトを順番に指すため、サイズは変わりません。

sys.getsizeof(MyClass().__dict__)利回りのテストも固定長です。Python ディクショナリはキーをkeysリストに格納し、値をリストに格納するためvalues(スマート ハッシュ アソシエーションなどを使用)。

したがって、クラスのサイズが大きくなるのを見たい場合は、次のようにします。

ipython からのダンプ

In [11]: class A():
   ....:     def __init__(self, **kwargs):
   ....:         for k,a in kwargs.items():
   ....:             self.__dict__[k]=a
   ....:
   ....:

In [14]: a1 = A(a=2)

In [15]: a2 = A(a=2,b=3,c='aaaa')

In [16]: import sys

In [17]: sys.getsizeof(a1.__dict__)
Out[17]: 140

In [18]: sys.getsizeof(a2.__dict__)
Out[18]: 140

In [19]: sys.getsizeof(a1.__dict__.keys())
Out[19]: 40

In [20]: sys.getsizeof(a2.__dict__.keys())
Out[20]: 48

In [21]: sys.getsizeof(a2.__dict__.keys()+a2.__dict__.values())
Out[21]: 60

In [22]: sys.getsizeof(a1.__dict__.keys()+a2.__dict__.values())
Out[22]: 52

これがあなたに何かを説明できることを願っています。

于 2013-06-13T15:40:22.887 に答える