Reputation: 191
I have two class structured as below
from abc import ABCMeta, abstractmethod
class C(metaclass=ABCMeta):
""""""
def __init__(self, x, y):
self._x = x
self._y = y
@property
@abstractmethod
def x(self):
"""Get the _x"""
@x.setter
@abstractmethod
def x(self, value):
"""Set the x"""
@property
def y(self):
"""Get the _y"""
@y.setter
def y(self, value):
"""Set the _y"""
class D(C):
""""""
def __init__(self, x, y):
self._x = x
self._y = y
@property
def x(self):
return self._x
@C.x.setter
def x(self, value):
self._x = value
@property
def y(self):
return self._y
@C.y.setter
def y(self, value):
self._y = value
When I initialize an instance of D. It throws a error: TypeError: Can't instantiate abstract class D with abstract methods x
When I rewrite setters decorator in D as
@x.setter
def x(self, value):
self._x = value
it works. But in python abc document https://docs.python.org/3/library/abc.html it states: in disappreciated @abc.abstractproperty If only some components are abstract, only those components need to be updated to create a concrete property in a subclass:
class D(C):
@C.x.setter
def x(self, val):
...
I don't know why write in this way will lead to error. Please help me understand the logic here. Thank you.
Upvotes: 1
Views: 49
Reputation: 282026
When you write @C.x.setter
above your setter, you're setting x
to a version of C.x
with the setter replaced with your new setter function. Only the setter - the getter you wrote earlier is discarded. You're still using C.x
's abstract getter.
The example in the docs uses @C.x.setter
because they want the behavior it provides. In the doc example, C.x
has a concrete getter, and they just want to replace the setter. That's not the case in your code.
Upvotes: 3