2016-06-23 2 views
12

난 그냥 파이썬에서 빈 클래스 크기 뒤에 근거를 알고, C에서 + + 모두가 빈 클래스의 크기가 항상 1 바이트를 보여줍니다 (지금까지 내가 본 것처럼)이 실행하자 시간의 객체를 생성하고, 파이썬에서 빈 클래스의 어떤 크기를 알아 내려고 : 내가파이썬에서 빈 클래스 크기

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

을 수행 할 때 나는 Empty이 많은 1016 (바이트) 걸리는 이유를 궁금해

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

및 ? 값 (1016)은 C++ 같은 절대 변경되지 않는 표준 값입니까? 파이썬 인터프리터에서 기본 클래스 최적화를 기대합니까? Empty의 크기를 줄일 수있는 방법이 있습니까? 호기심을 위해서)?

+0

내 컴퓨터에서 '104'를 반환합니다. – prashkr

+0

Python2.x에있는 경우이 https://repl.it/languages/python3 –

+1

의 코드를 실행했습니다. – 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을 반환하고 이전 스타일 클래스의 경우에는 0124를 반환합니다 (object에서 상속받지 않는 클래스). sys.getsizeof(Empty())은 새 스타일 클래스 인스턴스의 경우 28 개를, 이전 스타일의 경우 32 개를 반환합니다.


당신은 __slots__

이 클래스 변수를 사용하여 인스턴스의 크기를 줄일 수는 인스턴스에서 사용하는 변수 이름 문자열의 문자열, 반복 가능한, 또는 시퀀스를 할당 할 수 있습니다. __slots__은 선언 된 변수에 대해 공간을 예약하고 각 인스턴스에 대해 이 __dict____weakref__ 인 자동 생성을 방지합니다.

import sys 

class Empty(object): 
    __slots__ = [] 

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

출력

show 8 

이 기능을 사용하는 방법을 이해하기 위해 문서를 읽어 보시기 바랍니다.

+0

오후, dir (Empty) 할 때 볼 수있는 대부분의 것들이 연산자/메서드인데,이 메서드는 size()로 계산합니까? –

+0

@ 리차드 _G. 메서드의 실제 코드는 계산되지 않지만 메서드의 _pointer_는 계산됩니다. 마찬가지로리스트에서'sys.getsizeof'를 호출하면 목록 객체 자체의 크기와 목록에 참조 된 객체에 대한 모든 포인터의 크기를 얻습니다. 'sys.getsizeof'는 재귀 적으로 _not_되지 않습니다. –

+0

오후, 빈에 메서드를 추가하면 크기가 같아집니다 (메서드가 실제로 계산됩니다)? –

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()은 클래스 인스턴스입니다.

관련 문제