国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python的__slots__

wenhai.he / 1221人閱讀

摘要:任何類的實(shí)例對(duì)象包含一個(gè)字典類型為,通過(guò)這個(gè)字典將任意屬性綁定到對(duì)象上。就是完成這個(gè)功能的。允許子類重復(fù)繼承允許重復(fù)繼承若子類沒(méi)有,父類的對(duì)子類無(wú)效。

__slots__ 用處

__slots__的作用是阻止在實(shí)例化類時(shí)為實(shí)例分配dict,默認(rèn)情況下每個(gè)類都會(huì)有一個(gè)dict,通過(guò)__dict__訪問(wèn),這個(gè)dict維護(hù)了這個(gè)實(shí)例的所有屬性。

代碼:

# coding:utf-8
 
 
class Base(object):
    val = 1
 
    def __init__(self):
        pass
 
 
class BaseSlots(object):
    val = 1
    __slots__ = ("y",)
 
    def __init__(self):
        pass
 
 
class BaseSlots2(object):
    val = 1
    y = 2
    __slots__ = ("y",)
 
    def __init__(self):
        pass
 
 
b1 = Base()
print "b1.__dict__ is ", b1.__dict__  # b1.__dict__ is  {}
b1.x = 1
print "bi.x = 1, b1.__dict__ is ", b1.__dict__  # bi.x = 1, b1.__dict__ is  {"x": 1}
 
b2 = BaseSlots()
print "b2.__dict__ is ", b2.__dict__  # AttributeError: "BaseSlots" object has no attribute "__dict__"
b2.x = 1  # AttributeError: "BaseSlots2" object has no attribute "x"
b2.y = 3
print "b2.__dict__ is ", b2.__dict__  # AttributeError: "BaseSlots" object has no attribute "__dict__"
 
b3 = BaseSlots2()
print "b3.__dict__ is ", b3.__dict__  # AttributeError: "BaseSlots2" object has no attribute "__dict__"
b3.x = 1  # AttributeError: "BaseSlots2" object has no attribute "x"
b3.y = 3  # "BaseSlots2" object attribute "y" is read-only
print "b3.__dict__ is ", b3.__dict__  # AttributeError: "BaseSlots2" object has no attribute "__dict__"

輸出

# Base()輸出
b1.__dict__ is  {}
bi.x = 1, b1.__dict__ is  {"x": 1}

# BaseSlots()輸出
b2.__dict__ is
Traceback (most recent call last):
  File "test04.py", line 34, in 
    print "b2.__dict__ is ", b2.__dict__
AttributeError: "BaseSlots" object has no attribute "__dict__"

Traceback (most recent call last):
  File "test04.py", line 35, in 
    b2.x = 1
AttributeError: "BaseSlots" object has no attribute "x"


b2.__dict__ is
Traceback (most recent call last):
  File "C:/Users/fred1/PycharmProjects/test/test04.py", line 37, in 
    print "b2.__dict__ is ", b2.__dict__
AttributeError: "BaseSlots" object has no attribute "__dict__"

# BaseSlots2輸出
  File "test04.py", line 40, in 
    print "b3.__dict__ is ", b3.__dict__
AttributeError: "BaseSlots2" object has no attribute "__dict__"

Traceback (most recent call last):
  File "test04.py", line 41, in 
    b3.x = 1
AttributeError: "BaseSlots2" object has no attribute "x"

Traceback (most recent call last):
  File "test04.py", line 42, in 
    b3.y = 3
AttributeError: "BaseSlots2" object attribute "y" is read-only

Traceback (most recent call last):
  File "test04.py", line 43, in 
    print "b3.__dict__ is ", b3.__dict__
AttributeError: "BaseSlots2" object has no attribute "__dict__"

可見(jiàn):實(shí)例的 __dict__ 只保持實(shí)例的變量,對(duì)于類的屬性是不保存的,類的屬性包括變量和函數(shù)。由于每次實(shí)例化一個(gè)類都要分配一個(gè)新的dict,因此存在空間的浪費(fèi),因此有了__slots__,當(dāng)定義了__slots__后,__slots__中定義的變量變成了類的描述符,相當(dāng)于java,c++中的成員變量聲明,類的實(shí)例只能擁有這些個(gè)變量,而不在有__dict__,因此也就不能在增加新的變量。

Python 是一門(mén)動(dòng)態(tài)語(yǔ)言,可以在運(yùn)行過(guò)程中,修改對(duì)象的屬性和添加修改方法。任何類的實(shí)例對(duì)象包含一個(gè)字典__dict__ (類型為dictproxy), Python通過(guò)這個(gè)字典將任意屬性綁定到對(duì)象上。有時(shí)候我們只想使用固定的對(duì)象,而不想任意綁定對(duì)象,這時(shí)候我們可以定義一個(gè)屬性名稱集合,只有在這個(gè)集合里的名稱才可以綁定。__slots__就是完成這個(gè)功能的。

使用__slots__的主要原因是當(dāng)你只需要用預(yù)定義一系列屬性的簡(jiǎn)單對(duì)象,并且不需要攜帶__dict__方法時(shí)來(lái)節(jié)省空間。_PS:僅在你有大量實(shí)例的時(shí)候使用。_

# coding:utf-8
 
import sys
import pympler.asizeof as sf
# Pympler is a development tool to measure, monitor and analyze the memory behavior of Python objects in a running Python application.
 
 
class Slots(object):
    pass
 
 
class WithSlots(object):
    __slots__ = ("a", "b", "c")
 
    pass
 
 
n = Slots()
n.a, n.b, n.c = 1, 2, 3
w = WithSlots()
w.a, w.b, w.c = 1, 2, 3
 
print sys.getsizeof(n)  # 32

print sys.getsizeof(w)  # 36
 
print sf.asizeof(n)  # 296
 
print sf.asizeof(w)  # 136

# test in Python 2.7.10 

__slots__允許子類重復(fù)繼承

# coding:utf-8
 
import sys
import pympler.asizeof as sf
 
 
class A(object):
    __slots__ = "a"
    pass
 
 
class AB(A):
    __slots__ = "b"
    pass
 
 
ab = AB()
ab.a = ab.b = 23
 
 
class ABC(A):
    __slots__ = "a", "b"  # 允許重復(fù)繼承
    pass
 
 
abc = ABC()
abc.a = abc.b = 23
 
print sf.asizeof(ab)  # 88
print sf.asizeof(abc)  # 96
# test in Python 2.7.10 

若子類沒(méi)有__slots__,父類的__slots__對(duì)子類無(wú)效。

>>> class A(object): __slots__ = "a"
...
>>> a = A()
>>> a.b = 2
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: "A" object has no attribute "b"
>>> class B(A): pass
...
>>> b = B()
>>> b.b = 2
>>> b.b
2
>>>
Notes on using slots

Without a __dict__ variable, instances cannot be assigned new variables not listed in the __slots__ definition. Attempts to assign to an unlisted variable name raises AttributeError. If dynamic assignment of new variables is desired, then add __dict__ to the sequence of strings in the __slots__ declaration. Changed in version 2.3: Previously, adding __dict__ to the __slots__ declaration would not enable the assignment of new attributes not specifically listed in the sequence of instance variable names.

Without a__weakref__ variable for each instance, classes defining __slots__ do not support weak references to its instances. If weak reference support is needed, then add __weakref__ to the sequence of strings in the __slots__ declaration. Changed in version 2.3: Previously, adding __weakref__ to the __slots__ declaration would not enable support for weak references.

__slots__ are implemented at the class level by creating descriptors (3.4.2) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.

If a class defines a slot also defined in a base class, the instance variable defined by the base class slot is inaccessible (except by retrieving its descriptor directly from the base class). This renders the meaning of the program undefined. In the future, a check may be added to prevent this.

The action of a __slots__ declaration is limited to the class where it is defined. As a result, subclasses will have a __dict__ unless they also define __slots__.

__slots__ do not work for classes derived from ``variable-length"" built-in types such as long, str and tuple.

Any non-string iterable may be assigned to __slots__. Mappings may also be used; however, in the future, special meaning may be assigned to the values corresponding to each key.

擴(kuò)展閱讀
Saving 9 GB of RAM with Python’s slots

We’ve mentioned before how Oyster.com’s Python-based web servers cache huge amounts of static content in huge Python dicts (hash tables). Well, we recently saved over 2 GB in each of four 6 GB server processes with a single line of code — using __slots__ on our Image class.

Here’s a screenshot of RAM usage before and after deploying this change on one of our servers:

We allocate about a million instances of a class like the following:

class Image(object):
    def __init__(self, id, caption, url):
        self.id = id
        self.caption = caption
        self.url = url
        self._setup()
 
    # ... other methods ...

By default Python uses a dict to store an object’s instance attributes. Which is usually fine, and it allows fully dynamic things like setting arbitrary new attributes at runtime.

However, for small classes that have a few fixed attributes known at “compile time”, the dict is a waste of RAM, and this makes a real difference when you’re creating a million of them. You can tell Python not to use a dict, and only allocate space for a fixed set of attributes, by settings __slots__ on the class to a fixed list of attribute names:

class Image(object):
    __slots__ = ["id", "caption", "url"]
 
    def __init__(self, id, caption, url):
        self.id = id
        self.caption = caption
        self.url = url
        self._setup()
 
    # ... other methods ...

Note that you can also use collections.namedtuple, which allows attribute access, but only takes the space of a tuple, so it’s similar to using __slots__ on a class. However, to me it always feels weird to inherit from a namedtuple class. Also, if you want a custom initializer you have to override __new__ rather than __init__.

Warning: Don’t prematurely optimize and use this everywhere! It’s not great for code maintenance, and it really only saves you when you have thousands of instances.

參考

《python __slots__》

http://stackoverflow.com/questions/1816483/python-how-does-inheritance-of-slots-in-subclasses-actually-work

《Saving 9 GB of RAM with Python’s __slots__》

《使用__slots__》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/37883.html

相關(guān)文章

  • 如何優(yōu)化Python占用內(nèi)存

    摘要:概述如果程序處理的數(shù)據(jù)比較多比較復(fù)雜,那么在程序運(yùn)行的時(shí)候,會(huì)占用大量的內(nèi)存,當(dāng)內(nèi)存占用到達(dá)一定的數(shù)值,程序就有可能被操作系統(tǒng)終止,特別是在限制程序所使用的內(nèi)存大小的場(chǎng)景,更容易發(fā)生問(wèn)題。下面我就給出幾個(gè)優(yōu)化占用內(nèi)存的幾個(gè)方法。 概述 如果程序處理的數(shù)據(jù)比較多、比較復(fù)雜,那么在程序運(yùn)行的時(shí)候,會(huì)占用大量的內(nèi)存,當(dāng)內(nèi)存占用到達(dá)一定的數(shù)值,程序就有可能被操作系統(tǒng)終止,特別是在限制程序所使用...

    ThreeWords 評(píng)論0 收藏0
  • 通過(guò)Python__slots__節(jié)省9GB內(nèi)存

    摘要:我們之前提到過(guò),基于的服務(wù)器緩存了大量字典哈希表的靜態(tài)內(nèi)容。好啦,我們最近使用一行代碼在我們的類中使用,使得每個(gè)的服務(wù)器在處理中都節(jié)省超過(guò)內(nèi)存。一般說(shuō)來(lái),這很不錯(cuò),而且還支持完全動(dòng)態(tài)性,比如在運(yùn)行時(shí)設(shè)置任意新的屬性。 我們之前提到過(guò),Oyster.com基于Python的web服務(wù)器緩存了大量Python字典(dicts)(哈希表(hash tables))的靜態(tài)內(nèi)容。好啦,我們最近使...

    EastWoodYang 評(píng)論0 收藏0
  • classmethod&staticmethod 以及 __slots__

    摘要:什么是中的它的用途是什么裝飾器對(duì)應(yīng)的函數(shù)不需要實(shí)例化,不需要參數(shù),但第一個(gè)參數(shù)需要是表示自身類的參數(shù),可以來(lái)調(diào)用類的屬性,類的方法,實(shí)例化對(duì)象等。 什么是python中的classmethod,它的用途是什么? classmethod裝飾器對(duì)應(yīng)的函數(shù)不需要實(shí)例化,不需要 self 參數(shù),但第一個(gè)參數(shù)需要是表示自身類的 cls 參數(shù),可以來(lái)調(diào)用類的屬性,類的方法,實(shí)例化對(duì)象等。 cl...

    newsning 評(píng)論0 收藏0
  • 編寫(xiě)符合Python風(fēng)格對(duì)象

    摘要:自定義向量類型從自定義向量類型入手寫(xiě)出符合風(fēng)格的對(duì)象,這離不開(kāi)特殊方法的支持。將對(duì)象定為不可變的通過(guò)使用兩個(gè)前導(dǎo)下劃線。程序員約定使用一個(gè)下劃線前綴編寫(xiě)受保護(hù)的屬性即,他們認(rèn)為應(yīng)該使用命名約定來(lái)避免意外覆蓋屬性。 導(dǎo)語(yǔ):本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之面向?qū)ο笃闹攸c(diǎn)知識(shí)及個(gè)人心得,打算入門(mén)Python的朋友們可以來(lái)一起學(xué)習(xí)并交流。 本文重點(diǎn): 1、掌握編寫(xiě)Pythonic c...

    ethernet 評(píng)論0 收藏0
  • Python 面向?qū)ο缶幊蘋(píng)OP (二) slots,類多態(tài),繼承,復(fù)寫(xiě)方法

    摘要:需要注意的是的限定只對(duì)當(dāng)前類的對(duì)象生效,對(duì)子類并不起任何作用。本文的實(shí)例名稱均為杜撰,請(qǐng)不要對(duì)號(hào)入座我的其他文章已經(jīng)放到了上,如果感興趣的朋友可以去看看,鏈接如下精品練習(xí)題道實(shí)用技巧匯總教程 __slots__魔法 大家好,上一期我重點(diǎn)總結(jié)了有關(guān)類的基本知識(shí),現(xiàn)在簡(jiǎn)單回顧一下,順便加上一個(gè)創(chuàng)建類時(shí)常用的東西:__slots__ 首先創(chuàng)建一個(gè)名人類:Celebrity class Ce...

    Binguner 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<