Saturday, December 19, 2015

Python doesn't know the meaning of life :-)

By Vasudev Ram



Attribution of above image

I was checking out the repr() and __repr__() functions / methods of Python (in the process of creating an exercise for one of my students), when I came across this interesting 'feature' of Python:

I did this at the Python interpreter prompt (in both 2.7 and 3.4):

>>> ''.__repr__() # Call the dunder repr method on an empty string.
"''"
>>>

(Got the expected output - the representation of the empty string.)

Similarly for a list, a tuple, etc.:

>>> [].__repr__()
'[]'


>>> ().__repr__()
'()'

But when I did this:

>>> 42.__repr__()

I got this:

File "<stdin>", line 1
42.__repr__()
^
SyntaxError: invalid syntax

So, it looks like Python does not know the meaning of life :-)


Jokes apart, I also tried this (actually, before trying 42):

>>> 1.0.__repr__()
'1.0'

which worked. And the only difference between the example above that worked (1.0), and the two that did not (1 or 42), is that the latter two use an int, and the former uses a number with a decimal point.

But both also use the dot as the attribute access operator, which leads me to think that this is the reason for the issue (for ints): there is an ambiguity between interpreting 1.something as 1.other_decimal_digits (making it a floating point number) and as 1.some_attribute (making it an attribute access on an object) (because 1, like (almost) everything in Python, is an object (of type int), as can be seen by doing:

>>> dir(1)
and
>>> type(1)

Interested to know if anyone has a better explanation of this, and also of whether the same issue/anomaly, if it is one, occurs in any other languages, or if not, why not.

- Vasudev Ram - Online Python training and programming

Signup to hear about new products and services I create.

Posts about Python  Posts about xtopdf

My ActiveState recipes

5 comments:

Christian Heimes said...

The true meaning of life deserves some space:

>>> 42 .__repr__()
'42'

Дамјан said...

use (1).__repr__()

this is even documented somewhere in the reference or tutorial

yacc said...

It's an obvious case of lexing issues, e.g.:

1. => "1.0"
1.__repr__ => "1.0" __repr__ => oops, SyntaxError
(1).__repr__ => method wrapper

DaveMc said...

Not really an explanation, but an observation: if you put at least one space in between the 42 and the dot then python will accept it.

Vasudev Ram said...

Thanks to all those who commented.

Before writing the post, I had also tried this:

>>> a = 1
>>> a.__repr__()
'1'
>>>

which worked.