[Tutor] How is "set(ls).add('a') evaluated? [Was: Re: A program that can check if all elements of the list are mutually disjoint]

dn PyTutor at DancesWithMice.info
Sun Jun 6 17:54:08 EDT 2021


On 07/06/2021 05.22, boB Stepp wrote:
> On Sun, Jun 6, 2021 at 3:53 AM dn via Tutor <tutor at python.org> wrote:
>> On 06/06/2021 14.19, boB Stepp wrote:
>>> Ah, I finally see the light, dn!
>>
>> Regret to advise that such wisdom came from @David, not
>> this-David?self.David aka "dn".
> 
> My sincere apologies, David (*not* dn)!  I cannot seem to keep the
> "bouncing cats" segregated from the " dancing (with) mice" in my head,
> not to mention the same first names!

So let me get this straight: David gets the kudos *and* an apology -
whereas I'm told to pop-off...


>>> <Gripe>
>>> I find it really hard to remember which functions and methods return
>>> "None" and operate by side effect with those that return a new object.
>>> This is especially difficult for me as I so often have long breaks
>>> between using/studying Python.  I wish that Python had some sort of
>>> clever syntax that made it *obvious* which of the two possibilities
>>> will occur.
>>> </Gripe>
>>> ~(:>))
>>
>>
>> It's "pythonic"!
>> (hey, don't shoot me, I'm only the piano-player)

There are conventions at-play when help() and similar docs are composed.
At the higher level there are considerations of conveying detail whilst
also minimising the space required - the opposite applies (possibly)
when reading the Python Docs!

Secondly, a 'skill' for reading such (as mentioned) lies in aligning
one's thinking with the help()-idiom. For example, "We hold these truths
to be self-evident" that each method will be preceded either by "self."
(within the class definition) or 'object-name.' after instantiation.
Thus, "s.pop()".

Perhaps if we were to retro-fit the Python built-ins and PSL modules to
use "typing", that would make things more explicit?

<<<
It is recommended but not required that checked functions have
annotations for all arguments and the return type. For a checked
function, the default annotation for arguments and for the return type
is Any. An exception is the first argument of instance and class
methods. If it is not annotated, then it is assumed to have the type of
the containing class for instance methods, and a type object type
corresponding to the containing class object for class methods. For
example, in class A the first argument of an instance method has the
implicit type A. In a class method, the precise type of the first
argument cannot be represented using the available type notation.
>>>
(PEP-484 and after, https://www.python.org/dev/peps/pep-0484/)

Note that this PEP (and most) concentrates on automated features for its
justification, eg static checking; rather than any
documentation/readability factors!


Thus (from help() ):

 |  __and__(self, Set, /) -> Set
 |      Return self&value.
...
 |  add( Any ) [NB no -> return-value noted]
 |      Add an element to a set.
 |
 |      This has no effect if the element is already present.
...
 |  __len__(self, /) -> int
 |      Return len(self).
...
 |  pop( index:Optional[ Int ] ) -> element:Any
 |      Remove and return an arbitrary set element.
        Raises KeyError if the set is empty.
...
 |  update( Set) [NB no -> return-value noted]
 |      Update a set with the union of itself and others.
...


>> - where we can see that the set method "and" will return a new set
>> (logical given the result will be neither self nor the other set),
>> whereas set.add() will modify the contents of this existing set (stated
>> more categorically in the explanation for set.update() ):

> Ah, but here's the rub.  The help(set) and online docs when they
> describe the add() method do *not* _explicitly_ state what the method
> returns.  When reading this originally I naively thought it returned
> the updated set object.  OTOH, the union() method explicitly states
> what is returned.  I guess I am just dense and should have realized
> that if no *explicit* mention in the help and docs is made regarding a
> method's return value then it by default will return "None".  This now
> is making me even more of a believer in using type annotations and
> making it *very explicit* for dense people like me what the return
> value is for each method and function.  For me the docs and help()
> would read better if in every case for every function and method its
> return value is always explicitly stated.

Whilst there may be some improvement - what do you think?

It looks rather clumsy (to me), and one could argue that the lack of
return-value (in some cases), still requires the reader to notice and
appreciate the implication of its omission!

The balance here may be that help() is more an easy-access
reference/reminder tool. When it comes to 'learning' (or reacting to an
experiment resulting in "surprise") might the Python Docs be a better
(official) source? eg
https://docs.python.org/3.9/library/stdtypes.html#set-types-set-frozenset

Mea culpa: when trying something new, I often find that an aspect
lacking clarity (in my mind) in the docs, may be resolved by playing
with help() and the REPL - and equally, vice-versa!
-- 
Regards,
=dn


More information about the Tutor mailing list