[Python-ideas] Would it possible to define abstract read/write properties with decorators?
Darren Dale
dsdale24 at gmail.com
Fri Mar 18 18:29:52 CET 2011
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?
Darren
More information about the Python-ideas
mailing list