python - 如何禁止在 Python 中创建新的类属性?
问题描述
这可能看起来是一个非常基本的问题,但我在 SO 或其他地方找不到任何有用的东西......
如果您采用内置类,例如int
or 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__
属性的一种解决方案(除其他外),但禁止不需要的类属性的过程是什么,就像在内置类中所做的那样?
解决方案
@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
推荐阅读
- jquery - 将绑定应用于动态生成的 html
- ionic3 - Ionic 4 Tabs TypeError:无法在 getBackButton 处读取 null 的属性“querySelectorAll”
- python - 如何从 LinkExtractor() 或 scrapy.link.Link 对象获取 url 列表?(解决了)
- c++ - C++ 头文件:对头文件错误 g++ 中定义的函数的未定义引用
- python - 使用 Matplotlib 绘制动画股票的价格
- python - 无法在 PyCharm 版本 9.3.3 中安装 NumPy。Python 版本 3.8.2
- r - R:来自 tibble 的多个基因的 geom_logo
- google-apps-script - Google Scripts:根据 2 个不同的条件发送两封不同的电子邮件
- r - 循环遍历 R 数据以替换所有值
- laravel - Laravel + Vue.js - 如何拥有一个全局变量?