2001 Enchancement Wishlist

Alex Martelli aleaxit at yahoo.com
Fri Jan 5 11:57:01 EST 2001


"Raymond Hettinger" <othello at javanet.com> wrote in message
news:3A550331.594FEBDC at javanet.com...
    [snip]
> > > The decision to make a object a Singleton or to
> > > revoke that decision should be invisible to clients of the class.
> >
> > I strongly disagree that such "invisibility" is at all a desirable
> > design target -- and, in any case, "having __init__ return
> > something" would surely not accomplish it (or would you also
> > abolish 'is', 'id', etc...?).
>
> If a number of client's were already using the constructor, using
> singlify() saves the client's from having to remap from the constructor
> the were already using to a factory method of a different name.
>
> I don't get what you mean by abolishing 'is' and 'id'.

Sorry for being unclear!  What I meant is: client-code can already
tell whether two calls to FooBar() return the same object or two
different ones (for example, by checking with 'is', or comparing
the id() of the objects); so, the decision cannot be "invisible to
clients".

For real 'invisibility', don't expose Singletons: have class
FooBar turn into a (non-singleton) proxy for the real class
(rename it to _FooBar).  All FooBar objects delegate everything
to a single _FooBar object.  Identities remain distinct, so
'is' and id() keep working just as before; *state* is shared
(and behavior is identical for every FooBar instance), since
it's really the state and behavior of a single _FooBar instance.

I.e., module FooBar.py:

class _FooBar:
    # snip: whatever, lots & lots of stuff

class FooBar:
    theFooBar = _FooBar()
    def __init__(self):
        self.__dict__ = FooBar.theFooBar.__dict__
        self.__class__ = FooBar.theFooBar.__class__

and that's about it.  THIS level of delegation may easily be
considered too extreme, but it's easily exemplified -- just
to show how you can preserve identity distinctions while
merging state (the __dict__) and behavior (the __class__).

Now *this* ('weightless proxies') is a design pattern I
like...!-)


> > The more I do Python, the more I like "explicit is better than
implicit".
> >
> > Your request seems to boil down to having x implicitly mean x.keys(),
> > when x is a dictionary, in certain contexts; taking 'black magic' (even
> > in small doses:-) as a _negative_, rather than as good in itself, what
> > IS the supposed benefit that offsets the cost of implicitness here?
>
> The idea isn't totally out of left field.

I agree, it's not.  I just dislike it a bit, which says nothing
about the idea itself.

> Having tests for membership and
> an interator for dictionaries comes from Awk, Perl, and SmallTalk.
> Even plain English has an equivalent:  "Daddy, is Fragalistic IN the
> dictionary?"
>
> Benefit:  The proposed change is polymorphic with other parts of Python:
>     for c in "Arthur": print c                                   # strings
>     for k in ['lancalot', 'gallahad', 'robin']: print k    # lists
>     for e in (1,2,3): print e                                    # tuples
>     for k in knights: print k                                    # why not
> dictionaries?

Maybe my problem with it is related to my conceptualization of
the 'sequence abstraction' in Python -- it proceeds with simple
calls of __getitem__ (for class instances) for integers from 0
on up until IndexError gets raised to signify end-sequence.  It
seems to me that applying it to mappings would break the utter
(and very useful) underlying conceptualization, since it could
not be done via __getitem__.

strings, tuples and lists are sequences; mappings are not
sequences.  That's simple, to me... having a mapping be a
sequence in some respects would complicate things for me.

Membership-test would comparatively be no problem (since we now
have a dedicated special-method for that -- a mapping might just
translate that to has_key).


Alex






More information about the Python-list mailing list