[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

AltStyle によって変換されたページ (->オリジナル) /