python __slots__

python新模式的class,即从object继承下来的类有一个变量是__slots__,slots的作用是阻止在实例化类时为实例分配dict,默认情况下每个类都会有一个dict,通过__dict__访问,这个dict维护了这个实例的所有属性,举例如下
class base(object):
    v = 1
    def __init__(self):
          pass

b = base()
print b.__dict__
b.x = 2
print b.__dict__
运行:
{}
{'x':2}
可见:实例的dict只保持实例的变量,对于类的属性是不保存的,类的属性包括变量和函数。由于每次实例化一个类都要分配一个新的dict,因此存在空间的浪费,因此有了slots,当定义了slots后,slots中定义的变量变成了类的描述符,相当于java,c++中的成员变量声明,类的实例只能拥有这些个变量,而不在有dict,因此也就不能在增加新的变量
class base(object):
   __slots__ = ('y')
    v = 1
    def __init__(self):
          pass

b = base()
print b.__dict__
b.x = 2              //error,不能增加新的变量
print b.__dict__

注意,如果类的成员变量与slots中的变量同名,
class base(object):
    __slots=('y',)
   y = 2
    v = 1
    def __init__(self):
          pass

b = base()
print b.__dict__
b.x = 2
b.y = 3 //read only
print b.__dict__

目前的实现是该变量被设置为readonly!!!

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 raise an AttributeError. If dynamic assignment of new variables is desired, then add '__dict__' to the sequence of strings in the __slots__ declaration. (Changed in Python version 2.3)
  • 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 Python version 2.3)
  • __slots__ are implemented at the class level by creating descriptors ( 3.4.2.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.

你可能感兴趣的:(python,object,Class,Descriptor,attributes,variables)