Python中未重写抽象类的setter和deleter为何不报错?
这是Python抽象基类(ABC)和property装饰器的交互逻辑导致的:
父类抽象方法的注册规则
在Person类里,用@property + @abstractmethod定义name的抽象getter时,Python会把name这个名称加入类的__abstractmethods__集合。后面定义的setter和deleter,因为是绑定到同一个nameproperty对象上的,不会在__abstractmethods__里新增条目——ABC模块只把property的核心方法(也就是getter)标记为抽象方法。子类重写getter的作用
当子类Student定义了自己的@property def name(self)时,相当于用一个新的、非抽象的property对象覆盖了父类里标记为抽象的nameproperty。这时候ABC模块检查子类的__abstractmethods__集合,发现name已经有了实现(哪怕只有getter),就会认为子类不再是抽象类,允许实例化。未重写getter的报错原因
如果子类完全没定义name属性,父类里标记为抽象的name会被继承下来,__abstractmethods__集合里依然有name,ABC模块就会判定这是个没实现所有抽象方法的类,所以抛出TypeError禁止实例化。
说白了:Python的ABC只盯着property的getter有没有被实现,只要子类提供了name的getter(用@property装饰),就默认整个name抽象property已经被实现,不会去检查setter和deleter有没有重写。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

