【发布时间】:2019-03-18 12:32:15
【问题描述】:
在观看了 Nina Zahkarenko 在 Pycon2016 (link) 上的 Python 内存管理演讲后,似乎 dunder 方法 __slots__ 是一种减少对象大小和加速属性查找的工具。
我的期望是普通类会是最大的,而__slots__/namedtuple 方法会节省空间。但是,对sys.getsizeof() 的快速实验似乎表明并非如此:
from collections import namedtuple
from sys import getsizeof
class Rectangle:
'''A class based Rectangle, with a full __dict__'''
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
class SlotsRectangle:
'''A class based Rectangle with __slots__ defined for attributes'''
__slots__ = ('x', 'y', 'width', 'height')
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
NamedTupleRectangle = namedtuple('Rectangle', ('x', 'y', 'width', 'height'))
NamedTupleRectangle.__doc__ = 'A rectangle as an immutable namedtuple'
print(f'Class: {getsizeof(Rectangle(1,2,3,4))}')
print(f'Slots: {getsizeof(SlotsRectangle(1,2,3,4))}')
print(f'Named Tuple: {getsizeof(NamedTupleRectangle(1,2,3,4))}')
终端输出:
$ python3.7 example.py
Class: 56
Slots: 72
Named Tuple: 80
这里发生了什么?从 Python 的 Data Model 上的文档来看,__slots__ 似乎使用了描述符,这会给实现它的类增加函数开销。但是,为什么结果如此严重地偏向普通类?
引导我内心的 Raymond H.:必须有更艰难的方法!
【问题讨论】:
-
getsizeof没有报告类对象引用的数据结构的大小;只有类对象本身。
标签: python class documentation python-3.7