>>> b = Base()>>> b.a = 'a'Traceback (most recent call last):File "<pyshell#38>", line 1, in <module>b.a = 'a'AttributeError: 'Base' object has no attribute 'a'
或者子类另一个定义__slots__的类
class Child(Base):__slots__ = ('a',)
现在:
c = Child()c.a = 'a'
但是:
>>> c.b = 'b'Traceback (most recent call last):File "<pyshell#42>", line 1, in <module>c.b = 'b'AttributeError: 'Child' object has no attribute 'b'
from abc import ABC
class AbstractA(ABC):__slots__ = ()
class BaseA(AbstractA):__slots__ = ('a',)
class AbstractB(ABC):__slots__ = ()
class BaseB(AbstractB):__slots__ = ('b',)
class Child(AbstractA, AbstractB):__slots__ = ('a', 'b')
c = Child() # no problem!
将'__dict__'添加到__slots__以获得动态分配:
class Foo(object):__slots__ = 'bar', 'baz', '__dict__'
class Foo(object):__slots__ = 'foo', 'bar'class Bar(object):__slots__ = 'foo', 'bar' # alas, would work if empty, i.e. ()
>>> class Baz(Foo, Bar): passTraceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: Error when calling the metaclass basesmultiple bases have instance lay-out conflict
from peak.util.proxies import ObjectWrapper
class Original(object):def __init__(self):self.name = 'The Original'
class ProxyOriginal(ObjectWrapper):
__slots__ = ['proxy_name']
def __init__(self, subject, proxy_name):# proxy_info attributed added directly to the# Original instance, not the ProxyOriginal instanceself.proxy_info = 'You are proxied by {}'.format(proxy_name)
# proxy_name added to ProxyOriginal instance, since it is# defined in __slots__self.proxy_name = proxy_name
super(ProxyOriginal, self).__init__(subject)
if __name__ == "__main__":original = Original()proxy = ProxyOriginal(original, 'Proxy Overlord')
# Both statements print "The Original"print "original.name: ", original.nameprint "proxy.name: ", proxy.name
# Both statements below print# "You are proxied by Proxy Overlord", since the ProxyOriginal# __init__ sets it to the original objectprint "original.proxy_info: ", original.proxy_infoprint "proxy.proxy_info: ", proxy.proxy_info
# prints "Proxy Overlord"print "proxy.proxy_name: ", proxy.proxy_name# Raises AttributeError since proxy_name is only set on# the proxy objectprint "original.proxy_name: ", proxy.proxy_name
class Person:
__slots__ = {"birthday":"A datetime.date object representing the person's birthday.","name":"The first and last name.","public_variable":None,"_private_variable":"Description",}
help(Person)"""Help on class Person in module __main__:
class Person(builtins.object)| Data descriptors defined here:|| birthday| A datetime.date object representing the person's birthday.|| name| The first and last name.|| public_variable"""
import abc
class Slotted(abc.ABCMeta):
""" A metaclass that ensures its classes, and all subclasses,will be slotted types."""
def __new__(metacls, name, bases, attributes, **kwargs):""" Override for `abc.ABCMeta.__new__(…)` setting up aderived slotted class."""if '__slots__' not in attributes:attributes['__slots__'] = tuple()
return super(Slotted, metacls).__new__(metacls, name, # type: ignorebases,attributes,**kwargs)
# note no __slots__ declaration necessary with the metaclass:class Base(metaclass=Slotted):pass
# class is properly slotted, no __dict__:class Derived(Base):__slots__ = 'slot', 'another_slot'
# class is also properly slotted:class FurtherDerived(Derived):pass