如何在没有__dict__的情况下创建类对象

时间:2014-08-09 17:34:20

标签: python class python-3.x

class B(type):
    __slots__ = ()

class A(metaclass=B):
    pass

A.test = "test"

"A"是元类"B"的实例,"B"已定义__slots__ - 为什么我在课程__dict__ A?如何在没有__dict__的情况下创建类对象?

2 个答案:

答案 0 :(得分:3)

你不能这样做;班级总是__dict__

您只能在上使用__slots__来生成没有__dict__的实例,而不是元类型。您通常只生成一些类,因此在元类上支持__slots__没有太多要点

请勿使用__slots__来阻止设置属性。请改为使用__setattr__

class NoAttributesClassMeta(type):
    def __setattr__(cls, name, value):
        if name not in cls.__dict__:
            raise AttributeError("Cannot set attributes")
        type.__setattr__(cls, name, value)

答案 1 :(得分:2)

__slots__不会阻止您将属性设置为类,您需要覆盖__setattr__。这样的事情应该这样做:

class B(type):
    def __new__(cls, clsname, bases, dct):
        dct['__slots__']  = ('x',)
        return type.__new__(cls, clsname, bases, dct)
    def __setattr__(cls, attr, val):
        if attr not in cls.__slots__:
            raise AttributeError('Can\'t set {!r}'.format(attr))
        else:
            type.__setattr__(cls, attr, val)

class A(metaclass=B):
    pass

<强>演示:

>>> A.x = 1
>>> A.y = 2
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    A.y = 2
  File "C:\Python27\so.py", line 7, in __setattr__
    raise AttributeError('Can\'t set {!r}'.format(attr))
AttributeError: Can't set 'y'