Re: The trouble with classes
Serge Orlov <[email protected]>
| Newsgroups | gmane.comp.lang.prothon.user |
|---|---|
| Message-ID | <[email protected]> |
Paul Prescod wrote:
> Let's say that there is a cool class out there that you would like to
> derive from. But you don't want all of its behaviour. Just some. For
> instance there is a database table and you want to be able to read but
> not write. So that's easy:
> class MyTable(DbTable):
> def write():
> raise AttributeError("Not defined")
> Now imagine elsewhere in the code there is code that is trying to be
> careful about types. It doesn't want to call the "write" method on
> something unless it is a DbTable. So it has code like:
> if isinstance(obj, DbTable):
> obj.write(...)
> else:
> # do something else.
> This code throws an exception despite the type check. The type check was
> not helpful. The problem is that MyTable wanted DbTable's _behaviour_
> but it didn't want to declare that it IsA DbTable in the "I can do
> anything that you can do" sense. C++ has a notion of "private
> inheritance" to cover this case but most OO languages do not. Too many
> concepts bundled up into one thing!
It's not a trouble with classes it's a trouble with isinstance,
I already started a thread about that:
"isinstance considered harmful.":
http://www.prothon.org/pipermail/prothon-user/2004-June/001785.html
In your example you are just showing how to misuse isinstance, the
proper way to express what you want is to use protocols
instead of
> if isinstance(obj, DbTable):
> obj.write(...)
> else:
> # do something else.
you write
try:
workTable = WritableTable(obj)
workTable.write(...)
except NotWritableTable:
# do something else
Note that most of the time you don't need to catch the exception,
you just write in the documentation "pass to the function f only
writable tables". Now you can simply write
workTable = WritableTable(obj)
workTable.write(...)
and interface WritableTable will throw exception NotWritableTable
to the caller of function f.
-- Serge