为什么sys.getsizeof()对于两个实例报告相同的大小,即使一个实例具有额外的属性?

时间:2018-09-28 13:16:21

标签: python

import sys

class MyObject:
    def __init__(self,name,salary):
        self.name = name
        self.salary = salary

obj1 = MyObject("Tushar", 50)
obj2 = MyObject("Tushar", 50)
obj2.age = 20

print(sys.getsizeof(obj1))  # 56
print(sys.getsizeof(obj2))  # 56

obj2具有额外的age属性时,为什么def save(self, *args, **kwargs): delta = self.parking_off.date() - self.parking_on.date() if delta.days == 0: super().save(*args, **kwargs) else: day = self.parking_on booking_days = [] for i in range(delta.days+1): print('day variable is', day.date()) print('parking_off date is', self.parking_off.date()) if day.date() == self.parking_on.date(): booking_days.append( Parcare( user=self.user, email=self.email, parking_on=self.parking_on, parking_off=self.parking_on.replace(hour=18, minute=0, second=0), location=self.location ) ) day = day + datetime.timedelta(days=1) continue elif day.date() == self.parking_off.date(): booking_days.append( Parcare( user=self.user, email=self.email, parking_on=self.parking_off.replace(hour=9, minute=0, second=0), parking_off=self.parking_off, location=self.location ) ) else: booking_days.append( Parcare( user=self.user, email=self.email, parking_on=self.parking_on.replace(hour=9, minute=0, second=0) + datetime.timedelta(days=i), parking_off=self.parking_off.replace(hour=18, minute=0, second=0) - datetime.timedelta(days=delta.days-i), location=self.location ) ) day = day + datetime.timedelta(days=1) Parcare.objects.bulk_create(booking_days) 只有56个字节?

1 个答案:

答案 0 :(得分:3)

sys.getsizeof()仅为您提供系统内存用于直接引用。实例对象不直接存储属性 ,默认情况下,它们存储在由__dict__名称引用的字典对象中。而且字典也将键和值存储为引用,sys.getsizeof()只会为您提供字典内部C数组和其他内部簿记属性的内存大小,而不是键或值本身。

来自sys.getsizeof() documentation

  

仅考虑直接归因于对象的内存消耗,而不考虑其引用的对象的内存消耗。

您必须递归收集对象的大小,直到用完属性或键-值对等为止。文档链接到this example code,向您展示如何执行此操作。

该特定配方不支持实例,但是在此处传递对象的__dict__属性就足够了:

>>> total_size(obj1.__dict__)
303
>>> total_size(obj2.__dict__)
383

所以这两个对象的总大小属性字典不同。

请注意,Python在许多地方缓存或实习生对象,因此请不要将这些内存大小作为绝对值。例如,small integers are interned,因此在CPython内存中只有一个50整数对象,但是在上面的total_size()输出中它是单独计数的。

在假定给定类的绝大多数实例具有相同属性的前提下,现代CPython版本也可以通过拥有这两个实例share data on the keys__dict__字典对象来节省内存。

分析sys.getsizeof()数据时,请考虑到这一点。如果要分析Python的内存使用情况,最好先学习如何使用tracemalloc tool