On Mon, Nov 8, 2010 at 10:05 AM, Stefan Behnel <[email protected]> wrote:
> Darren Dale, 08.11.2010 15:34:
>> Python-2.6 extended the definition of property to include getter,
>> setter, and deleter methods that can be used as decorators. This
>> allows a really nice pattern for declaring properties without
>> populating the namespace with a bunch of private methods:
>>
>> class Foo(object):
>>
>>      _bar = None
>>     �...@property
>>      def bar(self):
>>          return self._bar
>>     �[email protected]
>>      def bar(self, val):
>>          self._bar = val
>>
>> What happens is @bar.setter makes a copy of bar, updates the copy to
>> use the decorated method as the setter, and returns the copy, which is
>> then bound to the name of the decorated function. The decorated
>> function has to be called bar, so that the updated copy is bound to
>> bar, replacing the original.
>>
>> Attempting to cythonize this example yields an error:
>>
>> $ python setup.py build_ext --inplace
>> running build_ext
>> cythoning test_property.pyx to test_property.c
>>
>> Error converting Pyrex file to C:
>> ------------------------------------------------------------
>> ...
>>      _bar = None
>>     �...@property
>>      def bar(self):
>>          return self._bar
>>     �[email protected]
>>      def bar(self, val):
>>     ^
>> ------------------------------------------------------------
>>
>> /Users/darren/temp/test/test_property.pyx:11:4: 'bar' already declared
>>
>> Would it be possible for Cython to support this pattern?
>
> The problem is not the property behaviour, it's the mapping from a Python
> function/method to a C function, which must have a unique name. Currently,
> functions are unique within one namespace, be it the module namespace or a
> class body namespace. They are actually looked up statically, not
> dynamically in definition order, so the fix is not as easy as adding a
> counted ID to the C-level name.
>
> The above might actually work if you change one of the method names, i.e.
> either the getter or setter name. If it works as you say, the setter name
> shouldn't have any impact on the result.

Sorry, I should have emphasized the point about the importance of the
setter name. It *must* be the same as the original property.

class Foo(object):

    _bar = None
    @property
    def bar(self):
        return self._bar
    @bar.setter
    def bar_(self, val):
        self._bar = val

That produces a class with two properties: bar and bar_. Foo.bar is a
property with a getter but no setter. Foo.bar_ is a property with a
getter and a setter.

Darren
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to