[Tutor] Expressions, literals, operator precedence (was: __abs__() not acting as expected)

Ben Finney ben+python at benfinney.id.au
Mon Mar 24 05:36:45 CET 2014


Jim Byrnes <jf_byrnes at comcast.net> writes:

> I am reading Practical Programming - An Introduction to Computer
> Science Using Python 3.  They give this example:
>
> >>> abs(-3)
> 3
>
> >>> -3 .__abs__()
> 3

That's a poor example, in my opinion. It's not good for an introductory
text to show calling dunder methods like that on an integer literal.

Perhaps you could communicate with the maintainer of that material, to
point out the problem with their example. Hopefully they will remove the
example from an introductory text.

> Python 3.3.5 (default, Mar 12 2014, 02:09:17)
> [GCC 4.6.3] on linux
>
> >>> abs(-3)
> 3
>
> >>> -3 .__abs__()
> -3

Yes, I get the same result as you.

The reason is that the expression is being evaluated as::

    -( (3) .__abs__() )

That is:

* Create the integer object 3

* Get the result of that object's ‘__abs__’ method

* Negate (invert the sign) of the value

(If you really care, see the end of this message[0] for a demonstration
that this is exactly what happens.)


Presumably the expression should be different, as shown in your next
example::

> If I use a variable it works.
>
> >>> x = -3
> >>> x.__abs__()
> 3

Yes, this is a better way to do it. But why are we calling the ‘__abs__’
function directly at all? That is, after all, the point of the ‘abs’
built-in function: to call the correct method on the object::

    >>> x = -3
    >>> abs(x)
    3

> I am curious as to what is happening.  Is the book wrong?  I checked
> it's errata and nothing is mentioned.

I think that this is both an erratum, and a demonstration that the
example is a bad idea for the book entirely. Can you contact the
maintainer of that work to let them know?


[0]::

    >>> import dis
    >>> dis.dis("-3 .__abs__()")
      1           0 LOAD_CONST               0 (3) 
                  3 LOAD_ATTR                0 (__abs__) 
                  6 CALL_FUNCTION            0 (0 positional, 0 keyword pair) 
                  9 UNARY_NEGATIVE       
                 10 RETURN_VALUE         

-- 
 \       “When I get new information, I change my position. What, sir, |
  `\             do you do with new information?” —John Maynard Keynes |
_o__)                                                                  |
Ben Finney



More information about the Tutor mailing list