我有一个class Fraction,它的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, dom及其各自的值。所以我试着做:if name not in Fraction().__dict__:
,我最终得到了一个无限递归错误。如何访问包含实例变量的字典?
您应该使用__slots__
来将属性限制为您想要的。
__slots__
允许显式声明数据成员(如属性)并拒绝创建__dict__
和__weakref__
(除非在__slots__
中显式声明或在父类中可用)
[…]如果没有
__dict__
变量,实例不能被分配__slots__
定义中未列出的新变量。尝试给未列出的变量名赋值会引发AttributeError
。[…]
所以基本上在你的类中添加这个,最好在顶部的某个地方(就在class
行之后,init之前):
__slots__ = 'num', 'denom'
并删除setattr:)