我希望下面的代码会引发AttributeError。我在做什么错了?
class CrazyClass:
def __init__(self, a):
self.a = a
self.b = 'b'
def difficult_set_attribute(key, value):
if key not in self.__dict__:
raise AttributeError('You may not set a new attribute, unless you do it in the secret way!')
self.__setattr__ = difficult_set_attribute
test = CrazyClass('a')
test.c = 'c' # why doesn't this raise AttributeError?
答案 0 :(得分:1)
已解决,因为@kindall说了什么:
class CrazyClass:
def __init__(self, a):
self.a = a
self.b = 'b'
# the assignment is only done at the first instantiation
if CrazyClass.__setattr__ is object.__setattr__:
def difficult_set_attribute(cls, key, value):
if key not in cls.__dict__:
raise AttributeError('You may not set a new attribute, unless you do it in the secret way!')
CrazyClass.__setattr__ = difficult_set_attribute
test = CrazyClass('a')
test.c = 'this raises AttributeError'
此解决方案的缺点是创建的第二个实例将引发AttributeError。
示例:
test = CrazyClass('a')
test_2 = CrazyClass('2')
可能有一个不太复杂的解决方案。我现在正在寻找。
编辑:这是我的解决方案,但是在此答案下阅读@kindal的新评论后,我也将实现他的解决方案:
class CrazyClass:
__temporary_allow_setattr = False
def __init__(self, a):
self.__temporary_allow_setattr = True
self.a = a
self.b = 'b'
self.__temporary_allow_setattr = False
if CrazyClass.__setattr__ is object.__setattr__:
def difficult_set_attribute(cls, key, value):
if key == '_CrazyClass__temporary_allow_setattr' or cls.__temporary_allow_setattr:
cls.__dict__[key] = value
else:
raise AttributeError('You may not set a new attribute, unless you do it in the secret way!')
CrazyClass.__setattr__ = difficult_set_attribute
test = CrazyClass('a')
test._CrazyClass__temporary_allow_setattr = True
test.c = 'this will succeed'
test_2 = CrazyClass('b')
test_2.c = 'this will fail'
答案 1 :(得分:0)
如果您仅定义__setattr__
来引发错误,那么它将起作用。
class CrazyClass:
def __init__(self, a):
self.a = a
self.b = 'b'
def __setattr__(self, key, value):
if key not in self.__dict__:
raise AttributeError('You may not set a new attribute, unless you do it in the secret way!')
test = CrazyClass('a')
test.c = 'c'