2013-06-13 1 views
2

어떤 종류의 데이터를 파이썬 인터 피터가 객체에 저장합니까? 추천
예를 들어, 코드의 다음파이썬 객체와 클래스의 메모리 레이아웃은 무엇입니까?

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,하지만 난이 추가 속성을 추가, 그래서 개체가 "더 큰"이 될 것을 생각한다. 글쎄, 결과는 그렇게 보이지 않는다.

+0

어떤 Python 버전입니까? 3.3에서는'c '는 32,'MyClass'는 488을 얻습니다. – delnan

+0

버전은 2.7.2입니다. – python

+0

그러면 MyClass는 구식 클래스입니다. 그것들은 피해야하며, 72 바이트의 대부분을 어떻게 든 차지한다면 놀라지 않을 것입니다. – delnan

답변

4

기본적으로 비단뱀 클래스와 인스턴스는 모두 개체입니다. MyClass()의 크기를 테스트 할 때 인스턴스 객체의 메모리 크기를 쿼리하고 MyClass을 입력하면 클래스 객체의 크기를 테스트합니다.

두 개체의 필드가 다르므로 그 크기가 다르며 클래스 개체가 인스턴스보다 많은 메모리를 필요로하는 것은 놀랄 일이 아닙니다.

파이썬에서 클래스의 인스턴스는 파이썬 객체 (함수, 필드 등)에 이름을 연결하는 일종의 사전입니다. 실제로, 그들은 MyClass().__dict__ 사전에 저장됩니다. 클래스가 필드를 차례로 저장하는 __dict__ 개체를 가리 키기 때문에 클래스에 필드를 더 추가하면 크기가 변경되지 않습니다.

sys.getsizeof(MyClass().__dict__)에 대한 테스트는 또한 고정 길이를 산출합니다. 파이썬 사전은 키를 keys 목록에 저장하고 그 값은 values 목록에 저장하기 때문에 (스마트 해시 연관 등). 이 당신에게 뭔가를 설명 할 수있는 희망

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 

ipython에서

덤프 :

그래서 당신은 당신이 할 수 성장 클래스의 크기를보고 싶다면.

+0

기본적으로,'sys.getsizeof()'는 완전히 쓸모 없다 (인터프리터 수정 비용을 결정할 때 제외). –

+0

내 관점에서 보면 C에서'sizeof'와 똑같이 작동합니다. 크기를 얻기 위해 참조를 따르지 않고 참조 된 객체를 가리키는 포인터의 크기를 반환합니다. 파이썬에서 메모리를 검사하는 다른 도구가 있습니다.당신은 그들을 시도 할 수 있습니다! –

+1

모든 것이 포인터이기 때문에'sys.getsizeof()'는 기본적으로 얼마나 많은 포인터가 객체에 있는지 알려주는 것입니다. 'C + K * n'과 같은 것을 얻을 수 있는데,'C'는 기본 객체 크기이고,'K'는 한 포인터의 크기이고,'n'은 자식 요소 (목록 항목 등)의 개수입니다. 그리고 dict의 경우에, 그것은 여러분에게 상수를줍니다. 이것은 거의 아무에게도 알려주지 않습니다. C에서는 포인터를 따라갈 수는 없지만 포인터가 아닌 많은 것들을 많이 알려줄 수 있습니다 (파이썬에서는 이와 동등하지 않습니다). –