python - 是否可以覆盖类的 __setattr__ ?

标签 python

在 Python 中,我知道可以这样说

>>> class C:
...   def __setattr__(self, name, value):
...     print("Hey, you can't set {0} to {1}!".format(name, value))
...
>>> x = C()
>>> x.y = 5
Hey, you can't set y to 5!

但以下仍然有效:

>>> C.y = 5
>>> print(C.y)
5

是否有可能获得如下功能:

>>> C.y = 5
Hey, you can't set y to 5!

纯粹出于好奇而提问,因为我真的想不出一个真正实用的例子。

最佳答案

像所有特殊方法一样,__setattr__ is accessed on the type ;对于类的实例,对于类,就是元类

您必须在自定义元类上定义它,而不是直接在类本身上定义它:

class SetAttrMeta(type):
    def __setattr__(cls, name, value):
        print("Hey, you can't set {0} to {1}!".format(name, value))

class C(metaclass=SetAttrMeta):
    pass

Python 然后在 type(C) 的返回值上查找 __setattr__,这里是 SetAttrMeta

演示:

>>> class SetAttrMeta(type):
...     def __setattr__(cls, name, value):
...         print("Hey, you can't set {0} to {1}!".format(name, value))
... 
>>> class C(metaclass=SetAttrMeta):
...     pass
... 
>>> C.spam = 'eggs'
Hey, you can't set spam to eggs!

关于python - 是否可以覆盖类的 __setattr__ ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24234407/

相关文章:

python换行符为10个元素

python - 当不同用户之间的底层表更改时,MySQL View 不会更新

python - 获取在 python pandas 中的任何行中包含特定值的列名

python - 无法将opencv图像拆分为RGB

python - Django 结果返回绝对 URL

二进制数据的 Python 字符串表示

python - 无法使用 Jupyter 在 Visual Studio Code 中运行 Python 代码 - "Jupyter kernel cannot be started from ' Python 3.6.8 64 位”

Python multiprocessing.Pool 不会立即启动

python - 使用 gcloud-python 在 Google Cloud Storage 中设置元数据

python - 在运行 'migrate' 命令之前删除 Django 迁移文件?