isinstance() considered harmful
Alex Martelli
aleax at aleax.it
Fri Jan 25 07:03:34 EST 2002
"Kragen Sitaker" <kragen at pobox.com> wrote in message
news:mailman.1011910117.27639.python-list at python.org...
...
> > I'll talk more about interfaces later. My question is,
> > are explicit interfaces considered harmful too?
>
> I really like the flexibility in Python that *any* value --- with a
> few exceptions --- can be of any type that implements the right
> interface. Explicit interfaces could provide this level of
> flexibility, but in Java, they don't.
To provide this level of flexibility, you have to be able to
supply a post-facto adapter for interfaces and classes that
were developed separately, and arrange for it to be used.
This is really needed for implicit interfaces, too, in fact.
Say I have an interface, or its implicit equivalent:
class kotrable:
# semantic specs snipped
def kotr(self): raise NotImplementedError
defined/used in framework X, eg in the crucial function:
def eat(lotsofstuff):
for x in lotsofstuff:
result = x(23)
result.kotr()
implying each item in lotsofstuff is a callable that,
when called with argument 23, returns a kotrable instance;
and a class defined/generated in framework Y:
class almostkotrable:
# mucho stuff snipped
def practicallykotr(self): print 'almost right'
e.g, with factories such as:
def afactory(x): return almostkotrable()
def another(x,y=45):
if x>y: return None
else: return almostkotrable()
and so on.
Now, I'd like to call X.eat((Y.afactory, Y.another)) or
something of the kind. I can't, of course. I need to
wrap each factory callable in Y into an adapter to
transform the almostkotrable instances into full-fledged
kotrable instances (or convincing ersatzes thereof,
in as much as X doesn't typetest), e.g.:
class myadapter(kotrable, almostkotrable):
kotr = practicallykotr
def __init__(self, wrapped):
self.__dict__ = wrapped.__dict__
def adaptingwrapper(factory):
def adapted(*args):
return myadapter(factory(*args))
return myadapter
and then I can finally code:
X.eat((myadapter(Y.afactory), myadapter(Y.another)))
Unfortunately, not all creational situations lend themselves
to wrapping/adapting so easily. Wouldn't it be wonderful if,
when framework X needed something respecting its X.kotrable
protocol, it did:
def eat(lotsofstuff):
for x in lotsofstuff:
result = x(23)
result = adapt(result, kotrable)
result.kotr()
and I could just register myadapter with the protocol
adaptation framework as the way to have Y.almostkotrable
instances adapted into fully X.kotrable ones? Ah, what a
bliss it would be...!
This is basically what PEP 246 proposes. Unfortunately, it
seems to be "just sleeping there", since almost a year. I
wonder if or how it could be helped along...
Alex
More information about the Python-list
mailing list