欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中的__slots__示例詳解

 更新時(shí)間:2017年07月06日 11:52:53   作者:Dongweiming  
在python新式類中,可以定義一個(gè)變量__slots__,它的作用是阻止在實(shí)例化類時(shí)為實(shí)例分配dict,下面這篇文章主要給大家介紹了關(guān)于Python中__slots__的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

相信Python老鳥都應(yīng)該看過那篇非常有吸引力的Saving 9 GB of RAM with Python's slots 文章,作者使用了__slots__讓內(nèi)存占用從25.5GB降到了16.2GB。在當(dāng)時(shí)來說,這相當(dāng)于用一個(gè)非常簡(jiǎn)單的方式就降低了30%的內(nèi)存使用,著實(shí)驚人。作者并沒有提到他的業(yè)務(wù)特點(diǎn)和代碼,那我們就基于《fluent python》中的例子來驗(yàn)證下是不是有這么厲害:

from __future__ import print_function
import resource
class A(object):
 def __init__(self):
 self.a = 'string'
 self.b = 10
 self.c = True
class B(object):
 __slots__ = ['a', 'b', 'c']
 def __init__(self):
 self.a = 'string'
 self.b = 10
 self.c = True
def test(cls):
 mem_init = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
 l = []
 for i in range(500000):
 l.append(cls())
 mem_final = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
 del l
 print('Class: {}:\n'.format(getattr(cls, '__name__')))
 print('Initial RAM usage: {:14,}'.format(mem_init))
 print(' Final RAM usage: {:14,}'.format(mem_final))
 print('-' * 20)
if __name__ == '__main__':
 import sys
 test(globals()[sys.argv[1].upper()])

我們分別跑一下這2個(gè)類:

❯ python mem_test.py a
Class: A:
Initial RAM usage: 4,890,624
 Final RAM usage: 200,454,144
--------------------
❯ python mem_test.py b
Class: B:
Initial RAM usage: 4,919,296
 Final RAM usage: 60,235,776

2種方法初始內(nèi)存略有差別,但是由于這個(gè)差別和總內(nèi)存量相比太小而忽略不計(jì),結(jié)論就是:

使用slots可以讓內(nèi)存使用減少3.5倍?。? 通過 (200 - 4) / ((60 - 4) * 1.0) 計(jì)算得來

那么用slot就是非非常那個(gè)有必要嗎?事實(shí)上500000個(gè)實(shí)例這種機(jī)會(huì)非常少見,用不用完全根據(jù)業(yè)務(wù)來決定,并不要以偏概全。因?yàn)椋ㄇ煤诎辶斯┦褂胈_slots__也是有副作用的:

  1. 每個(gè)繼承的子類都要重新定義一遍__slots__
  2. 實(shí)例只能包含哪些在__slots__定義的屬性,這對(duì)寫程序的靈活性有影響,比如你由于某個(gè)原因新網(wǎng)給instance設(shè)置一個(gè)新的屬性,比如instance.a = 1, 但是由于a不在__slots__里面就直接報(bào)錯(cuò)了,你得不斷地去修改__slots__或者用其他方法迂回的解決
  3. 實(shí)例不能有弱引用(weakref)目標(biāo),否則要記得把__weakref__放進(jìn)__slots__

第三點(diǎn)有點(diǎn)難理解,我寫個(gè)例子看看吧:

In [2]: %pycat ref_example.py
from weakref import ref
class A(object):
 __slots__ = ['b']
 def __init__(self):
 self.b = 1
class B(object):
 __slots__ = ['b', '__weakref__']
 def __init__(self):
 self.b = 1
In [3]: from ref_example import *
In [4]: a = A()
In [5]: r = ref(a)
---------------------------------------------------------------------------
TypeError     Traceback (most recent call last)
<ipython-input-6-75a6d689c8b3> in <module>()
----> 1 r = ref(a)
TypeError: cannot create weak reference to 'A' object
In [6]: b = B()
In [7]: r = ref(b)
In [8]: r
Out[8]: <weakref at 0x109199578; to 'B' at 0x10919f890>

所以實(shí)例不超過萬級(jí)別的類,__slots__是不太值得使用的。

PS: 《fluent python》比我狠,說的是小于百萬級(jí)別實(shí)例不值得使用。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

最新評(píng)論