function argument dependent on another function argument?

Aaron Brady castironpi at gmail.com
Sun Jan 18 12:16:28 EST 2009


On Jan 18, 10:44 am, Rob Williscroft <r... at freenet.co.uk> wrote:
> Aaron Brady wrote innews:6a10378f-addb-4d56-bc1b-0c382b3cb957 at t26g2000prh.googlegroups.com
> in comp.lang.python:
>
>
>
> > On Jan 18, 9:36 am, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> >> Steven D'Aprano <st... 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.  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
>
> > It is too bad that it is so much work to detect whether 'y' was passed
> > in the function call directly.  However, sentinel is just as good (or
> > nearly); at worst, you need one sentinel per argument per function,
>
> One per Module should be good enough. The only reason None doesen't
> suffice is that it has other legitimate uses.  Though to be honest
> I would always use None as the sentinel if it wasn't a legitimate
> argument.
>
> > which is possible to create, which has a specific meaning.  If you are
> > making systematic function calls, e.g. with a dictionary or list, you
> > can just use the sentinel in the dictionary.
>
> IIUYC then, one sentinel is still only needed as the missing argument
> is indicated by *both* position and value or by name and value (in the
> case of a keyword-dictionary), so seperate distinct sentinel objects
> aren't required, for example:
>
> SENTINEL = object()
>
> def f( a, b, c = SENTINEL, d = SENTINEL ):
>   print( "values: %r" % ( ( a, b, c, d ), ) )
>   if c is SENTINEL:
>     print( "c is missing" )
>   if d is SENTINEL:
>     print( "d is missing" )
>
> f( *( 1, 2, SENTINEL, SENTINEL ) )
>
> f( **dict( a = 1 , b = 2, d = 4 ) )
>
> f( **dict( a = 1 , b = 2, d = 4, c = SENTINEL ) )
>
> Rob.
> --http://www.victim-prime.dsl.pipex.com/

I don't have a concrete example, so you may prove to be right, but I'm
not convinced.

If you have one function with an argument that defaults to an empty
list, and calls another with an argument that defaults to an empty
dict, then what is the meaning of passing sentinel to the first one?
Whereas, if each had their own, then passing the first one's default
would mean the empty list, and passing the second one's default would
mean the dict.

(Or, even if that evaluates correctly, perhaps there is no such useful
program.)



More information about the Python-list mailing list