[PyQt] dip model types, properties, and syntax

Phil Thompson phil at riverbankcomputing.com
Thu Sep 2 16:29:31 BST 2010


On Wed, 25 Aug 2010 18:43:16 -0400, Darren Dale <dsdale24 at gmail.com>
wrote:
> On Wed, Aug 25, 2010 at 3:00 PM, Phil Thompson
> <phil at riverbankcomputing.com> wrote:
>> On Wed, 25 Aug 2010 14:27:55 -0400, Darren Dale <dsdale24 at gmail.com>
>> wrote:
>>> On Wed, Aug 25, 2010 at 1:17 PM, Phil Thompson
>>> <phil at riverbankcomputing.com> wrote:
>>>> On Sat, 14 Aug 2010 08:45:13 +0100, Phil Thompson
>>>> <phil at riverbankcomputing.com> wrote:
>>>>> On Mon, 9 Aug 2010 09:45:12 -0400, Darren Dale <dsdale24 at gmail.com>
>>>> wrote:
>>>>>> I have a question about using dip model attributes as properties.
The
>>>>>> documentation at
>>>>>>
>>>>>
>>>>
>>
http://www.riverbankcomputing.com/static/Docs/dip/model_tutorial.html#attributes-are-properties
>>>>>> gives an example:
>>>>>>
>>>>>> class ExampleModel(Model):
>>>>>>
>>>>>>     name = Str
>>>>>>
>>>>>>     def _get_name(self):
>>>>>>         return self._name
>>>>>>
>>>>>>     def _set_name(self, value):
>>>>>>         self._name = value
>>>>>>
>>>>>>     # method taken from previous section in documentation:
>>>>>>     def _default_name(self):
>>>>>>         import name_database
>>>>>>         return name_database.most_common_name()
>>>>>>
>>>>>>
>>>>>> Would it be possible for dip's model types to support the property
>>>>>> decorator syntax introduced in Python-2.6? If so, the above example
>>>>>> could then be implemented as:
>>>>>>
>>>>>> class ExampleModel(Model):
>>>>>>
>>>>>>     name = Str
>>>>>>
>>>>>>     @name.getter
>>>>>>     def name(self):
>>>>>>         return self._name
>>>>>>
>>>>>>     @name.setter
>>>>>>     def name(self, value):
>>>>>>         self._name = value
>>>>>>
>>>>>>     @name.default
>>>>>>     def name(self):
>>>>>>         import name_database
>>>>>>         return name_database.most_common_name()
>>>>>>
>>>>>> The virtue, aside from reusing an already familiar pattern in the
>>>>>> standard library, is that the ExampleModel namespace has fewer
>> exposed
>>>>>> private methods, which is desirable for models intended to be used
>> and
>>>>>> inspected in an interactive python environment like IPython.
>>>>>
>>>>> Hmm - interesting. It's more verbose but it is nicer. It could also
>>>>> support observers and allow declarative observers across classes. It
>> may
>>>>> also be faster.
>>>>
>>>> Unfortunately I can't think of a way to implement it. The problem
>> arises
>>>> because "name = Str" is allowed as a shortcut for "name = Str()" and
>>>> there
>>>> doesn't seem to be a way to implement (for example) getter() so that
it
>>>> can
>>>> cope with the different cases.
>>>
>>> Hmm. What if BaseType or ValueType did something like:
>>>
>>>     @classmethod
>>>     def property(cls, val):
>>>         if type(val) == types.FunctionType:
>>>             return property_factory(cls, getter=val)
>>>         else:
>>>             res = property_factory(cls, default=val)
>>>             return res.getter
>>>
>>> That may let you do:
>>>
>>> class Test(model):
>>>     @Str.property
>>>     def name(self):
>>>         return self._name
>>>
>>> or
>>>
>>> class Test(model):
>>>     #provide the default:
>>>     @Str.property('foo')
>>>     def name(self):
>>>         return self._name
>>>
>>> Is that a crazy idea?
>>
>> I don't like it because it doesn't follow the "standard" pattern you
>> first
>> mentioned. If we have to come up with a new pattern then I think the
>> current one is better.
> 
> Yes, I see your point.
> 
> Is there any chance you would consider dropping support for the "name
> = Str" syntax? This is just my opinion, but this syntax has always
> seemed awkward, not very pythonic. "You must have wanted an instance
> of this class, we'll take care of that for you" is kind of magical,
> it's fairly unusual behavior for python. People familiar with python
> but new to this pattern will look at "name = Str" and think "that
> attribute is a class, not an instance of the class, how are the two
> cases different?" Since an instance is what we are eventually going to
> end up with anyway, and Str has to be called with parentheses when we
> want to specify a static default value, maybe it would be clearer if
> only the standard Str() were supported. Plus, it would provide an
> opportunity to explore the decorator syntax, which may have additional
> benefits.

I can't disagree with any of your arguments. It's just that I'm so used to
"name = Str" from using Traits for so long.

I'll implement your suggestion then take a view overall as to what feels
nicer.

Phil


More information about the PyQt mailing list