function argument dependent on another function argument?

Rob Williscroft rtw at freenet.co.uk
Sun Jan 18 19:02:37 CET 2009


Aaron Brady wrote in
news:582ef883-0176-4984-9521-6c1894636891 at a26g2000prf.googlegroups.com
in comp.lang.python: 

> 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:
>>

>> > 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 ) )

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

I'm afraid I can't think of a use case for passing default values around
eiither, and I suspect if we were to come up with one, a better solution
that didn't involve passing default values around could be found.
 
> 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.

If you *mean* to pass an "empty list" or "empty dict"'s you should do 
it like:

  function_taking_list( [] )
  function_taking_dict( {} )

Its when you don't (have reason to) care that you need default arguments.

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

I agree, though I think some confusion arises here as there are two
(at least) distinct meanings for default arguments in python:

1) provide a value for when the caller doesn't, eg: 

    	def f( a = 1 ): ...

2) provide a cache for the functions /private/ use, eg:

    	def f( cache = {} ): ...

If the two are mixed up, then I can imagine a situation where somebody
might want to start passing default caches around.  It could only end
in tears.

Rob.
-- 
http://www.victim-prime.dsl.pipex.com/



More information about the Python-list mailing list