如何解决抽象类中属性setter的__isabstractmethod__不可写错误?
解决抽象类中Property Setter的AttributeError问题
你遇到的AttributeError: attribute '__isabstractmethod__' of 'property' objects is not writable错误,根源在于错误地用@abc.abstractmethod装饰了property的setter对象——property对象的__isabstractmethod__属性是只读的,abc模块无法修改它,因此触发报错。
错误代码的问题点
你原代码中setter的装饰器顺序颠倒了:
@abc.abstractmethod @current_light.setter def current_light(self, value: str) -> None: pass
这个写法会先创建一个setter类型的property对象,再试图用@abc.abstractmethod装饰这个对象,导致abc模块尝试修改其只读的__isabstractmethod__属性,最终报错。
解决方案
方案1:拆分抽象方法与Property绑定
将getter和setter分别定义为独立的抽象方法,再通过property()函数绑定为类属性:
import abc class MyClass(abc.ABC): @abc.abstractmethod def _get_current_light(self) -> str: """Current light setting.""" pass @abc.abstractmethod def _set_current_light(self, value: str) -> None: """Set the current lighting.""" pass current_light = property(_get_current_light, _set_current_light)
子类必须实现_get_current_light和_set_current_light两个抽象方法,才能完成实例化。
方案2:调整装饰器顺序(Python 3.3+适用)
保持装饰器语法,但调整顺序:先给方法添加@abc.abstractmethod,再用@current_light.setter装饰这个抽象方法:
import abc class MyClass(abc.ABC): @property @abc.abstractmethod def current_light(self) -> str: """Current light setting.""" pass @current_light.setter @abc.abstractmethod def current_light(self, value: str) -> None: """Set the current lighting.""" pass
这种写法中,抽象方法是底层的函数,@current_light.setter只是将其绑定为property的setter,abc模块会识别到底层方法的抽象标记,要求子类实现对应的setter逻辑。
内容的提问来源于stack exchange,提问作者Chukwuemeka Mordi
相关产品推荐
相关产品推荐

