'isa' keyword
talin at acm dot org
viridia at gmail.com
Fri Sep 2 13:06:41 EDT 2005
Thanks for all the respones :) I realized up front that this suggestion
is unlikely to gain approval, for reasons eloquently stated above.
However, there are still some interesting issues raised that I would
like to discuss.
Let me first respond to a few of the comments:
>What's the difference between this and ``isinstance`` ?
What's the difference between 'in' and 'has_key()"? 1) Its shorter and
more readable, 2) it can be overridden to mean different things for
different container types.
> What's wrong with:
> if image.isa(gif):
> elif image.isa(jpeg):
> elif image.isa(png):
That forces the classification logic to be put into the instance,
rather than in the category. With the "in" keyword, the "__contains__"
function belongs to the container, not the contained item, which is as
it should be, since an item can be in multiple containers.
> Especially conidering that checking parameters with "isinstance" is
> considered bad form with Python's duck typing.
Here's an example where the strict OOP style of programming breaks
down. I'll use SCons as an example. In SCons, there is a "Depends"
function that can take a filename, a list of filenames, or a build
target (which is a python object). So the logic looks like this:
def Depends( target ):
if isinstance( target, str ):
...
elif isinstance( target, list ):
...
elif isinstance( target, BuildTarget ):
...
else: error
You can't use method overloading here, because you are dealing with
builtin python objects (except for the BuildTarget).
I can think of several different cases where you would have to resort
to logic like this:
-- Where you are trying to distinguish between built-n python types
-- Where you are trying to distinguish between types that are created
by another, independent module and which you can't modify
-- Where you are trying to do multi-method dispatch logic.
As an example of the latter, imagine a music sequencer application that
edits a stream of Midi events. Lets suppose that there are various
"classes" of events:
Note On
Note Off
Aftertouch
Pitchbend
Control Change
In addition, lets suppose that we have a variety of different ways of
editing these events:
"Piano Roll" Editor - edits in horizontal "piano roll" form
"Drum Machine" editor - notes are placed on a grid
Event List Editor - a text list of events
Music Notation Editor - uses conventional notes and staves
All of these editors operate on the same underlying data, which is a
stream of events. Each of these editors has a "repaint" function to
render the stream of events. So the rendering of the event depends
*both* on the class of the event, and the class of the editor.
So you could organize it this way:
class PianoRollEditor:
def repaint( event ):
if isinstance( event, Note ): # draw note
elif isinstance( event, Aftertouch ): # draw
...etc
You could also invert the logic (which is somewhat clumsier):
class Note:
def repaint( context ):
if isinstance( context, PianoRollEditor ): ...
etc...
Now, I realize that some folks have built multi-method dispatch systems
for Python (I did one myself at one point.) However, these tend to be
somewhat slow and clunky without language support (and no, I am not
asking for Python to become Dylan or CLOS.) But it would be nice to
know if there was a cleaner way to solve the above problems...
More information about the Python-list
mailing list