__setattr__ 禁止更改 instance/self 变量?
__setattr__ to prohibit changes to instance/self variables?
我有一个 class 分数,它的 init 创建实例变量 self.num = num
和 self.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 :)
我有一个 class 分数,它的 init 创建实例变量 self.num = num
和 self.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 raisesAttributeError
. [...]
所以基本上在你的 class 添加这个,最好在顶部的某个地方(就在 class
行之后和 init 之前):
__slots__ = 'num', 'denom'
并删除您的 setattr :)