__setattr__ 禁止更改 instance/self 变量?

__setattr__ to prohibit changes to instance/self variables?

我有一个 class 分数,它的 init 创建实例变量 self.num = numself.denom=denom:

    def __init__(self,num=0,denom=1):
        assert isinstance(num, int), "Numerator and denominator must be an integer"
        assert isinstance(denom, int), "Numerator and denominator must be an integer"
        assert denom != 0, "Denominator cannot be 0."
        self.num = num
        self.denom = denom

并且我正在尝试编写它的 __setattr__ 方法来禁止在实例变量通过引发 NameError:

初始化后对其进行更改
    def __setattr__(self,name,value):
        if name not in Fraction.__dict__:
            self.__dict__[name] = value
        else:
            raise NameError

通过打印 Fraction.__dict__,我可以看到字典包含 Fractions 方法,而不是 num、denom 及其各自的值。所以我然后尝试做: if name not in Fraction().__dict__: 并且我最终遇到了无限递归错误。如何访问包含实例变量的字典?

您应该使用 __slots__ 来将属性限制为您想要的属性。

https://docs.python.org/3/reference/datamodel.html#slots

__slots__ allow us to explicitly declare data members (like properties) and deny the creation of __dict__ and __weakref__ (unless explicitly declared in __slots__ or available in a parent.)

[...] Without a __dict__ variable, instances cannot be assigned new variables not listed in the __slots__ definition. Attempts to assign to an unlisted variable name raises AttributeError. [...]

所以基本上在你的 class 添加这个,最好在顶部的某个地方(就在 class 行之后和 init 之前):

__slots__ = 'num', 'denom'

并删除您的 setattr :)