What is a function parameter =[] for?

Steven D'Aprano steve at pearwood.info
Sun Nov 22 05:06:24 EST 2015


On Fri, 20 Nov 2015 11:53 pm, BartC wrote:

> On 20/11/2015 12:28, Marko Rauhamaa wrote:
>> Even more appropriately, you may expressly want a mutable, singleton
>> object to be the default:
>>
>>     def initiate_query(query, database=global_database):
> 
> Finally, a down-to-earth example. 

Really? Astonishing. To me, the Ackermann's function is a straight-forward,
simple example. It is, after all, a pure mathematical function in the true
sense: it has no side-effects, it takes some arguments, and returns a
result. (Of course, the Python implementation I gave has the side-effect of
keeping a cache of past results, but that's just an implementation detail.)

Whereas this initiate_query example is the opposite of straight-forward. It
involves a database, which means side-effects. The very opposite of a pure
function. Besides, I've never written database code in my life, which makes
it weird and exotic to me. (If lambda is exotic to you because your
personal experience happens to have avoided that area, databases are
equally exotic to me for the same reason.

The lesson here is: programming covers a HUGE range of topics. Don't assume
that the blind-spots in your experience don't exist or aren't important,
because they will be to someone. What's exotic to you is boring and
common-place to somebody else, and vice versa.



> Here it probably doesn't matter at 
> what point 'global_database' gets bound. You know it will always refer
> to the current state of global_database, 

No. You've got that completely backwards.

With early binding semantics (or "early evaluation" if you prefer), the
default object will be the value of global_data at the time the function
declaration runs. Subsequent rebindings of the global variable will not
effect the default object one iota, and you will always know that the
default for database will always be the same thing, whatever it was when
you first defined the function:


global_database = DB("abc")
def initiate_query(query, database=global_database):
    ...

global_database = DB("xyz")

initiate_query(query)  # here, the database used is "abc", not "xyz"


But with late binding, or "late evaluation", the opposite is the case: when
you finally call initiate_query, the database used will be "xyz". *This*
time. Next time, it could be something else: or even nothing at all, if the
global variable has been deleted.




-- 
Steven




More information about the Python-list mailing list