Override property setter of base class in Python 3 - USE CASE

Nagy László Zsolt gandalf at shopzeus.com
Sun Sep 11 07:31:38 EDT 2016


> Even the problem seems to rather defeat the purpose of a property. A
> property should be very simple - why do you need to override it and
> call super()? Doesn't this rather imply that you've gone beyond the
> normal use of properties *already*?
Here are some of my classes that can represent data:

"FormField" - a field of a form that have some properties (name, label,
description, required or not, value etc.) They are available as
properties e.g. formfield.value, formfield.required etc.
"Form" - a collection of FormFields that can be used to validate the
form as a whole.

Some data structures are represented in FormField and Form instances. 
They are *often* represented to the user on a user interface. But
*sometimes* they are used in other ways.

The user interface is built on top of a "Widget" class, that knows how
to build ui elements for the user (in this case: in a web browser). It
can send/receive messages to/from the browser. Widget objects also have
basic properties (for example: color, size, parent widget etc.) Whenever
a property is changed on a widget object, the change is accounted for,
goes through some buffering and sent to the browser. When I do
"widget.visible = False" then it will (eventually) send a message to the
browser and execute javascript code something like this: 

jQuery("#some_widget_id").hide()

When a FormField needs a visual representation, then I create subclasses
that inherit from both Widget and FormField. For example, a "TextField"
class. Some properties that are defined in FormField must also be
represented visually. The synchronization between property values and
visual elements is done with messages/events. For example, when I do

textfield.value = "some value"

then the property value is updated internally in the FormField, but it
also creates a message that will be sent to the browser and update the
value attribute of the <input> element. As a result, the user will also
see that the value has been changed. On the other hand, when the user
changes the value in the <input> field, a message is pushed from the
browser to the TextField object, and that will also change the value of
the corresponding textfield.value property.

The "value of a form field" must have a unified interface. So when I do
" textfield.value = some_value " then I expect that the changed value
will be represented on the UI *if it has an UI representation*. The
widget needs to be able to intercept property value changes.

One solution would be to make FormField an observable object, define
separate events for these property changes (e.g. EVT_VALUE_CHANGED), and
let TextField listen to these events. But this is even more difficult
than using simple methods and overriding them.  We know that there will
only be a single chain of observers. Using an observable pattern that
can have many observers for a single event seems to be an overkill.
Using overriden setter methods instead of properties is still better
than using the observable/observer pattern. Much more simple and easier
to understand.

Does this go beyond the normal use of properties? You decide. I'm open
to suggestions. What other pattern can I use for this problem?

Here are the possibilities I see:

  * Use property virtualizers - too much syntax noise, but at least
    boilerplate code is contained within the class and it works as
    expected (this is what I use now)
  * Use getter/setter methods instead of properties - non-pythonic
  * Use the observable pattern, emit events for property changes and
    make others listen for it - too general and too difficult for this
    problem, harder to understand
  * Propose a new syntax that allows proper overriding of property
    getter/setter methods without too much syntax noise

   Laszlo





More information about the Python-list mailing list