2001 Enchancement Wishlist

Raymond Hettinger othello at javanet.com
Thu Jan 4 18:11:45 EST 2001


Alex Martelli wrote:    x = theModule.makeFoo(1,2)

> Really?  How does client-code use the classname _except_ as a
> constructor?  So, if you're so keen to avoid having it call makeFoo,
> just change your theModule.py as follows:
>
> [snip]
> # we currently singletonize it
>
> _singleFoo = Foo()
>
> def makeFoo():
>     return _singleFoo
>
> # and now, the magic trick...:
>
> Foo = makeFoo
> -- end of theModule.py
>
> Now, the client code doing
>
>     myFoo = theModule.Foo()
>
> will in fact be calling function theModule.makeFoo, which can
> return whatever you desire.  It doesn't make the singleton design
> pattern any better, mind you -- but neither does it make any
> worse; if you ARE keen to have a callable, named "just like" a
> class, which isn't the class itself, it's pretty elementary.
>

I tried your code and it worked well.  Cool!
It inspired me to create a general purpose singleton maker:

def singlify( obj ):
    "Transform an object's class into a Singleton"
    globals()[ obj.__class__.__name__ ] = lambda s=obj: s

counter = 0
class Foo:
    def __init__( self ):
        global counter
        counter += 1
        self.counter = counter
        if counter > 3:
            singlify(self)
    def __str__( self ):
        return str(self.counter)

# Client code prints:  1 2 3 4 4 4
for i in range(6):    print Foo(),


> > 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'.


> > Here is a revised wish (borrowed from AWK):
> >
> > Override the IN keyword for dictionaries and access the keys directly:
> >
> > knights = { 'lancalot':'good', 'gallahad':'brave', 'robin':'coward' }
> > for k in knights:
> >         print k, knights[k]
> > if 'arthur' in knights:
> >         print 'Not a king'
>
> 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.  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?


Thank you,

Raymond




More information about the Python-list mailing list