function argument dependent on another function argument?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Jan 18 17:28:04 EST 2009


On Sun, 18 Jan 2009 07:36:53 -0800, Paul Rubin wrote:

> Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> writes:
>> def foo(self, x, y=None):
>>     if y is None:
>>         y = self.a
>> 
>> I don't find that clumsy in the least. I find it perfectly readable and
>> a standard idiom.
> 
> That has the same problem as the earlier version.

No it doesn't. The earlier version had the problem that *any* false 
object is replaced by self.a. I'm just following the standard Python 
idiom of using None as a sentinel. Have a look through the standard 
library and see how many times it is used.

Built-ins rarely accept None as a sentinel, slice() being a conspicuous 
exception. This is sometimes a nuisance when writing wrappers:

def my_find(S, sub, start=None, end=None):
    """Like string.find() only with pre-processing."""
    pre_process()  # stub for something complicated
    if end is None and start is None:
        return S.find(sub)
    elif end if None:
        return S.find(sub, start)
    else:
        return S.find(sub, start, end)

or if you prefer:

def my_find(S, sub, start=None, end=None):
    """Like string.find()"""
    pre_process()
    args = [sub]
    if start is not None:
        args.append(start)
        if end is not None:
            args.append(end)
    return S.find(*args)


Having said that, there are times where you need to pass None as a 
legitimate argument and not as a sentinel. In that case, your solution:

> If the person passes
> None, they get self.a.  I prefer:
> 
>     sentinel = object()
>     ...
> 
>     def foo(x, y=sentinel):
>       if y is sentinel:
>           y = self.a

is an excellent one.


-- 
Steven



More information about the Python-list mailing list