[Python-Dev] [PEP] += on return of function call result (original) (raw)

Luke Kenneth Casson Leighton lkcl@samba-tng.org
Fri, 16 May 2003 14:24:51 +0000


On Fri, May 16, 2003 at 08:07:23AM -0400, Andrew Koenig wrote:

ark> Why can't you do this?

ark> for t in range(5): ark> for r in range(10): ark> foo = log.setdefault(r,'') ark> foo += "test %d\n" % t Luke> after running this code, Luke> log = {0: '', 1: '', 2:'', 3: '' ... 9: ''} Luke> and foo equals "test 5". Then that is what foo would be if you were able to write log.setdefault(r,'') += "test %d\n" % t as you had wished.

hmm...

..mmmm...

you're absolutely right!!!

Luke> if, however, you do this:

Luke> for t in range(5): Luke> for r in range(10): Luke> foo = log.setdefault(r,[]) Luke> foo.append("test %d\n" % t) Luke> then empirically i conclude that you DO end up with the Luke> expected results (but is this true all of the time?) I presume that is because you are now dealing with vectors instead of strings. In that case, you could also have written for t in range(5): for r in range(10): foo = log.setdefault(r,[]) foo += ["test %d]n" % t] with the same effect. Luke> the reason why your example, andrew, does not work, is Luke> because '' is a string - a basic type to which a pointer is Luke> NOT returned i presume that the foo += "test %d"... returns a Luke> DIFFERENT result object such that the string in the dictionary Luke> is DIFFERENT from the string result of foo being updated. Well, yes. But that is what you would have gotten had you been allowed to write log.setdefault(r,"") += in the first place.

[i oversimplified in the example, leading to all the communication problems.

the actual usage i was expecting is based on {}.setdefault(0, []) += [1,2] rather than setdefault(0, '') += 'hh'

]

Luke> can anyone tell me if there are any PARTICULAR circumstances where

Luke> foo = log.setdefault(r,[]) Luke> foo.append("test %d\n" % t) Luke> will FAIL to work as expected? It will fail if your expectations are incorrect or unrealistic.

... that sounds like a philosophical or "undefined" answer rather than the technical one i was seeking

... but it is actually quite a useful answer :)

to put the question in a different way, or to say again, to put a different, more specific, question:

can anyone tell me if there are circumstances under which the second argument from setdefault will SOMETIMES be copied instead of returned and SOMETIMES be returned as-is, such that operations of the type being attempted will SOMETIMES work as expected and SOMETIMES not?

Luke> andrew, sorry it took me so long to respond: i initially Luke> thought that under all circumstances for all types of foo, Luke> your example would work.

But it does! At least in the sense of the original query.

where the sense was mistaken, consequently the results are not, as you rightly pointed out, not as expected.

The original query was of the form

Why can't I write an expression like f(x) += y? and my answer was, in effect, If you could, it would have the same effect as if you had written foo = f(x) foo += y and then used the value of foo. Perhaps I'm missing something, but I don't think that anything you've said contradicts this answer.

based on this clarification, my queries are two-fold:

  1. what is the technical, syntactical or language-specific reason why I can't write an expression like f(x) += y ?

  2. the objections that i can see as to why f(x) += y should not be allowed to work are that, as andrew points out, some people's expectations of any_function() += y may be unrealistic, particularly as normally the result of a function is discarded.

    however, in the case of setdefault() and get() on dictionaries, the result of the function is NOT discarded: in SOME instances, a reference is returned to the dictionary item.

    under such circumstances, why should the objections - to disallow {}.setdefault(0, []) += [] or {}.get([]) += [] - stand?

l.