On 18/11/2015 23:22, Chris Angelico wrote:
On Thu, Nov 19, 2015 at 10:14 AM, BartC <b...@freeuk.com> wrote:
On 18/11/2015 22:11, Ian Kelly wrote:

On Wed, Nov 18, 2015 at 2:08 PM, fl <rxjw...@gmail.com> wrote:

Hi,

I have tried the below function and find that it can remember the
previous
setting value to 'val'. I think the second parameter has something on
this
effect, but I don't know the name and function of '=[]' in this
application.

Could you explain a little to me?
Thanks,


def eList(val, list0=[]):
      list0.append(val)
      return list0
list1 = eList(12)
list1 = eList('a')


The list0 parameter has a default value, which is [], an initially
empty list. The default value is evaluated when the function is
defined, not when it is called, so the same list object is used each
time and changes to the list are consequently retained between calls.


That is really bizarre behaviour.

So, looking at some source code, a default value for certain types is only
certain to be that value for the very first call of that function?

On the contrary, it is certain always to be that exact object.

But, not the same value that appears as the default?

 >>> The default value is evaluated when the function is
defined, not when it is called

Given the amount of pointless dynamic stuff that goes on in Python, I'm
surprised they've overlooked this one!

It seems simple enough to me to check for a missing parameter, and to assign
whatever default value was designated ([] in this case). (How does the
default mechanism work now?)

It's exactly the way Ian described it. Functions are defined, not
declared - it's an executable statement. When the 'def' statement is
reached, the expressions in the argument defaults get evaluated, and
the results get saved into the function's attributes:
....

Sorry, I didn't understand any of that. Let's try a simpler example like the OP's. There's this innocuous looking function that you are interested in calling:

 def fn(a=[]):
 #   print ("Function fn called with",a)
 |   a.append(10)
 |   return a

It appends a value to its argument and returns the result.

It looks like at first like, if called with no argument, it will return [10].

But what it actually returns depends on the entire call history since the program started executing, something you probably have no knowledge of and no control over. So if fn has previously been called a million times with no argument, then after this call:

 x=fn()

x contains a list of a million tens, not one. I'd say most people would be rather surprised by that.

I suspect those same people (unless they are experts in the murky corners of the language) would expect:

  x=fn()

when fn specifies a default argument of [], to be the same as writing:

  x=fn([])

and not be dependent on fn's entire call history.

Your solution of using:

  def fn(a=None):

is not really satisfactory. Partly because it now utilities two mechanisms for the default: first to get None, then some extra code to get []. But also it's no longer obvious how the function works and what the default is. At least, you can't tell from a glance at the start of the function that [] is the default.

--
Bartc


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to