我只是想知道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的大小(只是为了好奇心?)
答案 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()
是一个类实例。