[Python-ideas] Would it possible to define abstract read/write properties with decorators?
Guido van Rossum
guido at python.org
Fri Mar 18 19:36:01 CET 2011
On Fri, Mar 18, 2011 at 10:29 AM, Darren Dale <dsdale24 at gmail.com> wrote:
> On Sun, Mar 13, 2011 at 12:49 PM, Darren Dale <dsdale24 at gmail.com> wrote:
>> On Sun, Mar 13, 2011 at 11:18 AM, Darren Dale <dsdale24 at gmail.com> wrote:
>> [...]
>>> It seems like it should be possible for Python to support the
>>> decorator syntax for declaring abstract read/write properties. The
>>> most elegant approach might be the following, if it could be
>>> supported:
>>>
>>> class Foo(metaclass=ABCMeta):
>>> # Note the use of @property rather than @abstractproperty:
>>> @property
>>> @abstractmethod
>>> def bar(self):
>>> return 1
>>> @bar.setter
>>> @abstractmethod
>>> def bar(self, val):
>>> pass
>>>
>>> I thought that would work with Python-3.2, but Foo is instantiable
>>> even though there are abstractmethods. If python's property could be
>>> tweaked to recognize those abstract methods and raise the usual
>>> TypeError, then we could subclass the abstract base class Foo in the
>>> usual way:
>>
>> Here is a working example!:
>
> The modifications to "property" to better support abstract base
> classes using the decorator syntax and @abstractmethod (rather than
> @abstractproperty) are even simpler than I originally thought:
>
> class Property(property):
>
> def __init__(self, *args, **kwargs):
> super(Property, self).__init__(*args, **kwargs)
> for f in (self.fget, self.fset, self.fdel):
> if getattr(f, '__isabstractmethod__', False):
> self.__isabstractmethod__ = True
> break
>
>>
>> class C(metaclass=abc.ABCMeta):
>> @Property
>> @abc.abstractmethod
>> def x(self):
>> return 1
>> @x.setter
>> @abc.abstractmethod
>> def x(self, val):
>> pass
>>
>> try:
>> c=C()
>> except TypeError as e:
>> print(e)
>>
>> class D(C):
>> @C.x.getter
>> def x(self):
>> return 2
>>
>> try:
>> d=D()
>> except TypeError as e:
>> print(e)
>>
>> class E(D):
>> @D.x.setter
>> def x(self, val):
>> pass
>>
>> print(E())
>>
>
> running this example yields:
>
> Can't instantiate abstract class C with abstract methods x
> Can't instantiate abstract class D with abstract methods x
> <__main__.E object at 0x212ee10>
>
> Wouldn't it be possible to include this in python-3.3?
Sounds good to me.
--
--Guido van Rossum (python.org/~guido)
More information about the Python-ideas
mailing list