2016-06-23 1 views
12

私は空のクラスのサイズの背後にある根拠を、Pythonで知りたいだけです。C++では、空のクラスのサイズが常に1バイトを表示することを知っています。独自のオブジェクトを作成するための時間、私はPythonで空のクラスのどのようなサイズを見つけるためにしよう:Pythonで空のクラスのサイズ

class Empty:pass # i hope this will create empty class 

と私は

import sys 
print ("show",sys.getsizeof(Empty)) # i get 1016 

を行う際Emptyは、このくらいの1016(バイト)かかり、なぜ私が疑問に思います?また、それが返す値(1016)は、C++のように(ほとんど)変更しない標準値ですか?Pythonインタプリタからベースクラスの最適化を期待していますか?Emptyのサイズを減らす方法はありますか好奇心のためだけに)?

+0

私のマシンで '104'を返します。 – prashkr

+0

は、私はあなたがPython2.x –

+1

'104'に私のコードを実行し、それはすでにいくつかの荷物が付属しています' object'を継承します。 'dir(Empty)'を見てください。空リストではありません! – styvane

答えて

14

あなたは64ビットバージョンのPython 3を実行していると仮定します。32ビットPython 3.6(Linux)では、コードはshow 508と表示されます。

しかし、それは基底クラスobjectクラスからかなり多くのものを継承するクラスオブジェクト自体のサイズです。代わりに、あなたのクラスのインスタンスのサイズを取得した場合、結果ははるかに小さくなります。 たくさんよりコンパクトである私のシステムでは、

import sys 

class Empty(object): 
    pass 

print("show", sys.getsizeof(Empty())) 

出力

show 28 

。 :)

FWIWは、Pythonの2.6.6に、sys.getsizeof(Empty)新しいスタイルのクラスのために448を返し、ちっぽけな44古いスタイルのクラス(objectから継承していないもの)のために。 sys.getsizeof(Empty())は、新しいスタイルのクラスのインスタンスでは28、古いスタイルでは32を返します。あなたはこのクラス変数__slots__

を使用して、インスタンスのサイズを小さくすることができ


は、文字列、反復可能オブジェクト、またはインスタンスが使用する変数名と 文字列の順序を割り当てることができます。 __slots__は、宣言された変数のために スペースを予約し、各インスタンスに対して の__dict____weakref__の自動作成を防止します。

import sys 

class Empty(object): 
    __slots__ = [] 

print("show", sys.getsizeof(Empty())) 

出力

show 8 

この機能を使用する方法を理解するドキュメントをお読みください。

+0

PM、私がdir(Empty)をしたときに私が見ることのできるもののほとんどは演算子/メソッドですが、メソッドはsize()でカウントされますか? –

+0

@リチャード_G。メソッドの実際のコードはカウントされませんが、メソッドの_pointer_はカウントされます。同様に、リスト上で 'sys.getsizeof'を呼び出すと、リストオブジェクト自体のサイズと、リスト内で参照されているオブジェクトへのすべてのポインタのサイズだけが取得されます。 'sys.getsizeof'は再帰的ではありません。 –

+0

PM、Emptyのメソッドを追加すると、サイズは同じになります(メソッドは本当にカウントされます)? –

2
Python 2.7.11 (default, Apr 12 2016, 14:09:35) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin 
>>> class Empty:pass 
>>> import sys 
>>> print ("show",sys.getsizeof(Empty)) # i get 1016 
('show', 104) 
>>> print ("show",sys.getsizeof(Empty())) 
('show', 72) 

1016バイト。ご覧のとおり、これは実装固有のものです。その他の興味深いのサイズ、使用して、新しいスタイルのクラス:

>>> print ("show",sys.getsizeof(object())) 
('show', 16) 
>>> class Empty2(object):pass 
>>> print ("show",sys.getsizeof(Empty2)) 
('show', 904) 
>>> print ("show",sys.getsizeof(Empty2())) 
('show', 64) 

空のクラス定義がまだクラス定義、したがって、クラスオブジェクト(more here)である:クラス定義が入っている

、新しいですネームスペースが作成され、ローカルスコープとして使用されます。

クラス定義が正常に(最後から)残ると、クラスオブジェクトが作成されます。これは基本的に クラス定義によって作成された名前空間の内容のラッパーです...

すべてのクラスのオブジェクトを使用すると、実行して見属性の最小セットがあります。

>>> dir(Empty) 
['__doc__', '__module__'] 
>>> dir(Empty2) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

をと他の実装の詳細も、予想以上に大きかったサイズの理由です。最後に

、そのクラスのインスタンスはクラスオブジェクトほどの大きな期待通り、確かにかなり小さく、ないこと。注意してくださいEmptyはクラスオブジェクトです。 Empty()はクラスインスタンスです。

関連する問題