首页 > 解决方案 > 如何禁止在 Python 中创建新的类属性?

问题描述

这可能看起来是一个非常基本的问题,但我在 SO 或其他地方找不到任何有用的东西......

如果您采用内置类,例如intor list,则无法为它们创建额外的类属性(这显然是一种可取的行为):

>>> int.x = 0
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    int.x = 0
TypeError: can't set attributes of built-in/extension type 'int'

但是如果您创建自己的自定义类,则默认情况下不会激活此限制,因此任何人都可以在其中创建其他类属性

class foo(object):
    a = 1
    b = 2

>>> foo.c = 3
>>> print(foo.a, foo.b, foo.c)
1 2 3

我知道类属性是禁止创建不需要的实例__slots__属性的一种解决方案(除其他外),但禁止不需要的属性的过程是什么,就像在内置类中所做的那样?

标签: pythonattributes

解决方案


@AlexisBRENON 的答案有效,但如果您想模拟内置类的行为,其中允许子类覆盖属性,您可以将__frozen属性设置为True仅当bases参数为空时:

class FrozenMeta(type):
    def __new__(cls, name, bases, dct):
        inst = super().__new__(cls, name, bases, {"_FrozenMeta__frozen": False, **dct})
        inst.__frozen = not bases
        return inst
    def __setattr__(self, key, value):
        if self.__frozen and not hasattr(self, key):
            raise TypeError("I am frozen")
        super().__setattr__(key, value)

class A(metaclass=FrozenMeta):
    a = 1
    b = 2

class B(A):
    pass

B.a = 2
B.c = 1 # this is OK
A.c = 1 # TypeError: I am frozen

推荐阅读