zoukankan      html  css  js  c++  java
  • 浅谈__slots__

    __slots__在python中是扮演属性声明(Attribute Declaration)的角色,当然属性本身不用声明,只需要在使用前赋值即可,但是实际上,属性的应用远非在使用前赋值就行,所以有attribute declaration, attribute accessor,attribute management 等概念,本文对__slots__属性声明做一个学习总结,其他的之后会陆续总结。

    (1)Why __slots__?

    __slots__用来限制类的实例的属性,优化内存(为每个实例都分配命名空间,如果很多实例被建立起来,然而需要较少的属性,就会很浪费内存空间,所以,python对每个slot 属性在每个实例中都保留了足够空间),防止出现码字错误(typos)等。

    但是,它也打破了python核心的动态性质,比如,任何命名通过赋值就可以创建,因此它们应当在非常清楚的真的需要的时候使用,引用python 手册的原话:

    Best reserved for rare cases where there are large numbers of instances in a memory-critical application.

    (2)__slots__基本用法

    __slots__用在新类型类中(New-Style class)是类属性,为列表,其中包含了该类实例的属性,类实例化后,仅允许创建在__slots__列表中的属性,如果定义的属性不在其中,则抛出AttributeError异常。以下代码简单的展示了其基本用法:

    >>> class c:
        __slots__=['a','b']
    
        
    >>> x=c()
    >>> x.a
    Traceback (most recent call last):
      File "<pyshell#4>", line 1, in <module>
        x.a
    AttributeError: a
    >>> x.a=1
    >>> x.b=2
    >>> x.a,x.b
    (1, 2)
    >>> x.c=8
    Traceback (most recent call last):
      File "<pyshell#8>", line 1, in <module>
        x.c=8
    AttributeError: 'c' object has no attribute 'c'

    (3)注意事项

    (a)__slots__与命名空间字典__dict__

    有slots的实例,有些根本就没有__dict__属性,有些实例的属性不在__dict__中。接上面代码,继续...

    >>> x.__dict__
    Traceback (most recent call last):
      File "<pyshell#9>", line 1, in <module>
        x.__dict__
    AttributeError: 'c' object has no attribute '__dict__'

    而没有命名空间字典(namespace dictionary)__dict__,就意味着不可能为实例创建一个不在slots中的属性,怎么办?可以通过把__dict__也写到__slots__中来解决。

    >>> class c:
        __slots__=['a','b','__dict__']
    
        
    >>> x=c()
    >>> x.a=1;x.b=2;x.c=3
    >>> x.a,x.b,x.c
    (1, 2, 3)
    >>> x.__dict__
    {'c': 3}

    可以看到可以创建一个x.c,而c不在slots中,在__dict__中。而getattr方法可以对slots中的属性进行访问。接上面代码:

    >>> getattr(x,'a');getattr(x,'b')
    1
    2

    (b)在超类(superclass)中的多重__slot__

    __slots__是一个类属性,所以子类的slots会继承父类的slots。

    >>> class E:
        __slots__=['c','d']
    
        
    >>> class D(E):
        __slots__=['a','__dict__']
    
        
    >>> x=D()
    >>> x.a=1;x.c=2;x.d=3;x.e=8
    >>> x.a,x.d,x.c,x.e
    (1, 3, 2, 8)
    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    Python中的装饰器之@wraps(四)
    python中装饰器之有参装饰器(三)
    python中装饰器之叠加装饰器(二)
    python中装饰器之闭包函数(一)
    python中的命名空间
    函数的嵌套与迭代
    函数对象
    matlab学习checkbox使用
    matlab学习滚动条改变文本数值
    matlab学习GUI可调的界面窗口
  • 原文地址:https://www.cnblogs.com/johnyang/p/10463138.html
Copyright © 2011-2022 走看看