Idiom gone, or did it really ever exist? () is ()

Delaney, Timothy tdelaney at avaya.com
Wed Apr 18 02:34:59 EDT 2001


> > Over the years, I've occasionally used this idiom:
> > 
> > NULLARGUMENT = ()
> > 
> > def someFunctionOrMethod  (argument = NULLARGUMENT ):
> >     if argument is NULLARGUMENT:
> >         doSomething()
> >     else:
> >         doSomethingElse()
> > 
> > That is, I was attempting to distinguish between a call 
> where argument is
> > passed a NULL tuple and a call where argument is passed 
> nothing at all.
> > When I was working on unit tests for my current piece of 
> code, however, I
> > discovered that this no longer works (Python 1.5.2).  No 
> idea for how long
> > it hasn't worked.  Now, of course, I could have used:
> 
> 
> The convention is to use 'None' for this purpose. 'None' 
> never changes, so
> 'argument is None' will work correctly for you.

This will not actually work for the purpose though. The idea is to
distinguish between whether a parameter was passed, or whether the default
parameter is being used. Note: I've never tried this myself ...

If you have a default of None, it is impossible to determine this if the
user passes None - because it will be the same instance of None in almost
all cases.

Obviously, previously all tuples were distinct objects, even if they
compared the same. Thus this technique worked. However, some tuples are now
obviously being interned (the empty tuple for example), meaning that if a
user passes an empty tuple you can no longer distinguish the two.

# Will never work

def func (p=None):
    if p is None:
        print 'Default parameter'
    else:
        print 'Parameter passed'

func()      # prints 'Default parameter'
func(None)  # prints 'Default parameter'

# Will work if empty tuple is not interned

__nullArgument = ()

def func (p=__nullArgument):
    if p is __nullArgument:
        print 'Default parameter'
    else:
        print 'Parameter passed'

func()      # prints 'Default parameter'
func(())    # we want it to print 'Parameter passed',
            # will probably print 'Default parameter'

# Should always work

class nullArgument:
    """"""

__nullArgument = nullArgument()

def func (p=__nullArgument):
    if p is __nullArgument:
        print 'Default parameter'
    else:
        print 'Parameter passed'

func()                  # prints 'Default parameter'
func(nullArgument())    # prints 'Parameter passed'

# There is a better way to do this one though ...

class __nullArgument:
    """"""

__nullArgument = __nullArgument()

def func (p=__nullArgument):
    if p is __nullArgument:
        print 'Default parameter'
    else:
        print 'Parameter passed'

# Now *can't* pass an instance of the class, so it will never compare true

Tim Delaney




More information about the Python-list mailing list