git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Questioning the effects of multiple assignment


On Tue, Jul 7, 2020 at 2:30 AM Mike Dewhirst <miked at dewhirst.com.au> wrote:

>
> -------- Original message --------From: dn via Python-list <
> python-list at python.org> Date: 7/7/20  16:04  (GMT+10:00) To: 'Python' <
> python-list at python.org> Subject: Questioning the effects of multiple
> assignment TLDR; if you are a Python 'Master' then feel free to skim the
> first part (which you should know hands-down), until the excerpts from 'the
> manual' and from there I'll be interested in learning from you...Yesterday
> I asked a junior prog to expand an __init__() to accept either a series of
> (>1) scalars (as it does now), or to take similar values but presented as a
> tuple. He was a bit concerned that I didn't want to introduce a (separate)
> keyword-argument, until 'we' remembered starred-parameters. He then set
> about experimenting. Here's a dichotomy that surfaced as part of our
> 'play':-(my problem is: I can't (reasonably) answer his question...)If you
> read this code:NB The print-ing does not follow the input-sequence, because
> that's the point to be made... >>> def f( a, *b, c=0 ):Shouldn't that def
> be ...>>> def f(a, c=0, *b):???...     print( a, type( a ) )...     print(
> c, type( c ) )...     print( b )... >>> f( 1, 'two', 3, 'four' )[I had to
> force "c" to become a keyword argument, but other than that, we'll be using
> these three parameters and four argument-values, again]Question 1: did you
> correctly predict the output?1 <class 'int'>0 <class 'int'>('two', 3,
> 'four')Ahah, "c" went to default because there was no way to identify when
> the "*b" 'stopped' and "c" started - so all the values 'went' to become "b"
> (were all "consumed by"...).Why did I also print "b" differently?Building
> tension!Please read on, gentle reader...Let's make two small changes:-
> amend the last line of the function to be similar:...     print( b, type( b
> ) )- make proper use of the function's API: >>> f( 1, 'two', 3, c='four'
> )Question 2: can you predict the output of "a"? Well duh!(same as before)1
> <class 'int'>Question 3: has your predicted output of "c" changed? Yes?
> Good!(Web.Refs below, explain; should you wish...)four <class
> 'str'>Question 4: can you correctly predict the content of "b" and its
> type?('two', 3) <class 'tuple'>That makes sense, doesn't it? The arguments
> were presented to the function as a tuple, and those not assigned to a
> scalar value ("a" and "c") were kept as a tuple when assigned to "b".Jolly
> good show, chaps!(which made my young(er) colleague very happy, because now
> he could see that by checking the length of the parameter, such would
> reveal if the arguments were being passed as scalars or as a tuple.Aside:
> however, it made me think how handy it would be if the newly-drafted PEP
> 622 -- Structural Pattern Matching were available today (proposed for
> v3.10, https://www.python.org/dev/peps/pep-0622/) because (YAGNI-aside)
> we could then more-easily empower the API to accept other/more
> collections!Why am I writing then?Because during the same conversations I
> was 'demonstrating'/training/playing with some code that is (apparently)
> very similar - and yet, it's not. Oops!Sticking with the same, toy-data,
> let's code: >>> a, *b, c = 1, 'two', 3, 'four' >>> a, type( a ) >>> c,
> type( c ) >>> b, type( b )Question 5: what do you expect "a" and "c" to
> deliver in this context?(1, <class 'int'>)('four', <class 'str'>)Happy so
> far?Question 6: (for maximum effect, re-read snippets from above, then)
> what do you expect from "b"?(['two', 3], <class 'list'>)List? A list?
> What's this "list" stuff???When "b" was a parameter (above) it was assigned
> a tuple!Are you as shocked as I?Have you learned something?(will it ever be
> useful?)Has the world stopped turning?Can you explain why these two
> (apparently) logical assignment processes have been designed to realise
> different result-objects?NB The list cf tuple difference is 'legal' - at
> least in the sense that it is documented/expected behavior:-Python
> Reference Manual: 7.2. Assignment statementsAssignment statements are used
> to (re)bind names to values and to modify attributes or items of mutable
> objects:...An assignment statement evaluates the expression list (remember
> that this can be a single expression or a comma-separated list, the latter
> yielding a tuple) and assigns the single resulting object to each of the
> target lists, from left to right....A list of the remaining items in the
> iterable is then assigned to the starred target (the list can be empty).
> https://docs.python.org/3/reference/simple_stmts.html#assignment-statementsPython
> Reference Manual: 6.3.4. CallsA call calls a callable object (e.g., a
> function) with a possibly empty series of arguments:...If there are more
> positional arguments than there are formal parameter slots, a TypeError
> exception is raised, unless a formal parameter using the syntax *identifier
> is present; in this case, that formal parameter receives a tuple containing
> the excess positional arguments (or an empty tuple if there were no excess
> positional arguments).
> https://docs.python.org/dev/reference/expressions.html#calls--
> Regards,=dn-- https://mail.python.org/mailman/listinfo/python-list
> --
>
Dunno about the rest of the list but I'm finding this message incredibly
hard to read.

Please sir - - - - would you please break up your message into at least
sentences?

Regards