怎样使用python中的__slots__方法
创始人
2024-11-18 16:41:05
0次

__slots__的简介

__slots__是可以在定义Python类时添加的属性。

您可以使用对象实例可以拥有的可能属性来定义插槽。

使用__slots__的方法如下:

class WithSlots:
    __slots__ = ('x', 'y')
 
    def __init__(self, x, y):
        self.x, self.y = x, y

使用__slots__的更高层次的最大原因是:

1.由于数据结构优化而更快地获取和设置属性;

2.减少了类实例的内存使用量。 不想使用它的某些原因是,

3.如果类具有在运行时更改的属性(动态属性),或者存在复杂的对象继承树。

我们做个测试数据:

首先,我们先进行一些测试,以查看__slots__何时更快,从批量实例化开始。 使用Python的“ timeit”模块和此代码段,我们得到以下结果:

class WithoutSlots:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
 
class WithSlots:
    __slots__ = ('x', 'y', 'z')
 
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
 
def instance_fn(cls):
    def instance():
        x = cls(1, 2, 3)
return instance
Without Slots: 0.3909880230203271
With Slots: 0.31494391383603215
(averaged over 100000 iterations)

在这种情况下,使用slots的实例化速度稍快。 这很有意义,因为我们拒绝为给定对象的新实例创建__dict__。 字典通常比元组或列表有更多内存开销。 让我们尝试一个具有更多与实例相关联的属性的类!

Without Slots: 1.5249411426484585
With Slots: 1.52750033326447
(averaged over 100000 iterations)

通常,使用__slots__并不能真正缩短实例化时间。 尽管不必创建__dict__,但是还有其他开销需要我们稍后再使用的slots来完成,这导致了类似于从实际类中复制字典的运行时间。

当我们开始快速连续获取和设置值时,真正的加速就起作用了:

def get_set_fn(cls):
    x = cls(list(range(26)))
    def get_set():
        x.y = x.z + 1
        x.a = x.b - 1
        x.d = x.q + 3
        x.i = x.j - 1
        x.z = x.y / 2
return get_set
Without Slots: 11.59717286285013
With Slots: 9.243316248897463
(averaged over 100000 iterations)

速度提高了20%以上! 如果测试范围更广(并且不总是访问相同的属性,且属性的长度比单个字符长),则可以实现更大的加速。

内存使用情况

首先,让我们测试元组和字典在内存中的增长方式之间的区别。 当使用__slots__知道给定实例可以存在哪些属性时,它可以为与实例相关联的描述符分配(而不必为每个新对象添加__dict__)。

在Python中,很难描述对象实例使用的确切内存量:sys.getsizeof仅适用于基元和内置函数。 相反,我们将在名为“ Pympler”的库中使用名为asizeof的函数。

import sys  #没有这一句会报错
sys.getsizeof(('a', 'b', 'c', 'd'))
>>> asizeof(('a', 'b', 'c', 'd'))
304
>>> asizeof({'a': 'b', 'c': 'd'})
512
>>> asizeof(tuple(string.ascii_lowercase))
1712
>>> dictionary
{'e': 'f', 'k': 'l', 'c': 'd', 'g': 'h', 'o': 'p', 'i': 'j', 's': 't', 'm': 'n', 'q': 'r', 'a': 'b', 'y': 'z', 'w': 'x', 'u': 'v'}
>>> asizeof(dictionary)
2320

我们在这里省略了__slots__示例的实现细节:我们没有将一个元组用于描述符,一个元组用于值,而是将它们全部放在一个列表中。 但是,与元组和dict之间的差异相比,我们发现大小的差异并不大:

>>> asizeof(('a', 'b')) + asizeof(('c', 'd'))
352
为了更好的测量,当我们在上一个示例类的slots上实际运行asizeof时,会发生以下情况:
>>> w1 = WithoutSlots(1, 2, 3)
>>> asizeof(w1)
416
>>> w2 = WithSlots(4, 5, 6)
>>> asizeof(w2)
160

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...