python中的空类大小

时间:2016-06-23 11:48:13

标签: python

我只是想知道python中空类大小背后的基本原理,在C ++中,每个人都知道空类的大小总是会显示1个字节(据我所知)这让运行时创建唯一对象,我试图找出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解释器中进行任何零基类优化?有没有什么办法可以减小am的大小(只是为了好奇心?)

2 个答案:

答案 0 :(得分: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

这是 lot 更紧凑。 :)

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

请阅读文档以了解如何使用此功能。

答案 1 :(得分: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()是一个类实例。