object.enable() anti-pattern

Chris Angelico rosuav at gmail.com
Fri May 10 13:24:59 EDT 2013


On Sat, May 11, 2013 at 1:44 AM, Serhiy Storchaka <storchaka at gmail.com> wrote:
> 10.05.13 15:19, Robert Kern написав(ла):
>
>> I'd be curious to see in-the-wild instances of the anti-pattern that you
>> are talking about, then.
>
>
> Many (if not most) GUI frameworks use this pattern.
>
>     button = Button("text")
>     button.setForegroundColor(...)
>     button.setBackgoundColor(...)
>     button.setFont(...)
>     button.setRelief(...)
>     button.setBorder(...)
>     button.setWidth(...)
>     button.setAction(...)
>     button.setMouseListener(...)
>     button.place(...)

The button really exists, though. You could merge the creation and
placement (or in the case of a window/dialog, the creation and
showing), but it's often useful to not. However, in the specific case
you have there, there's an alternative: a mapping of attributes and
values passed to the constructor, and then you could pass the
constructed object directly to a place(). That would let you, if you
wished, effectively construct a Button with a parent right there,
which makes reasonable sense.

> Another example is running a subprocess in Unix-like systems.
>
>     fork()
>     open/close file descriptors, set limits, etc
>     exec*()

Hrm. Not really a corresponding example. After you fork, you have two
actual processes. Following up with an exec is only one of the
possible options; I've done code that forks and execs, and code that
forks and keeps running, and neither of them feels "wrong" in any way.
There IS a function that's similar to what you're saying, and that's
vfork:

"""
(From POSIX.1) The vfork() function has the same effect as fork(2),
except that the behavior is undefined if the process created by
vfork() either modifies any data other than a variable of type pid_t
used to store the return value from vfork(), or returns from the
function in which vfork() was called, or calls any other function
before successfully calling _exit(2) or one of the exec(3) family of
functions.
"""

It's deprecated because it's so fragile (and because regular fork()
isn't that much less efficient now; AIUI, vfork was meant to be a
lightweight fork). I would say that the deprecation of vfork in favour
of fork is a strong indication that the object.enable() anti-pattern
can come up in kernel APIs too, and isn't liked there either.

ChrisA



More information about the Python-list mailing list