Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it a syntax error to invoke a method on a numeric literal in Python?

Tags:

python

syntax

I can invoke methods on numbers only when I bind them to a name:

>>> a = 5
>>> a.bit_length()
3

I can invoke methods on string literals:

>>> 'Hello World'.lower()
'hello world'

But I cannot invoke methods on numeric literals:

>>> 5.bit_length()

This raises a SyntaxError. Is there a practical reason for that, or is it historic?

Edit Just found this related question that shows workarounds (that have already been suggested here as well). I guess this also answers the main question - with simple workarounds available, there probably wasn't enough benefit to making the grammar more complex (and harder to parse) to make this work.

like image 324
Björn Pollex Avatar asked Apr 10 '14 09:04

Björn Pollex


People also ask

Why am I getting syntax errors in Python?

The Python SyntaxError occurs when the interpreter encounters invalid syntax in code. When Python code is executed, the interpreter parses it to convert it into bytecode. If the interpreter finds any invalid syntax during the parsing stage, a SyntaxError is thrown.

How do I fix invalid SyntaxError in Python?

You can clear up this invalid syntax in Python by switching out the semicolon for a colon. Here, once again, the error message is very helpful in telling you exactly what is wrong with the line.

What is a numeric literal in Python?

What are numeric literals? Numeric literals are used to represent numbers in a python program.In python we have different types of numeric literals such as integers, floating point numbers and complex numbers. Integers in python are numbers with no fractional component.

What is SyntaxError in Python with example?

Syntax errors are mistakes in the use of the Python language, and are analogous to spelling or grammar mistakes in a language like English: for example, the sentence Would you some tea? does not make sense – it is missing a verb. Common Python syntax errors include: leaving out a keyword.


2 Answers

The floating point numbers are parsed as per the following rules, quoting from the docs,

floatnumber   ::=  pointfloat | exponentfloat
pointfloat    ::=  [intpart] fraction | intpart "."
exponentfloat ::=  (intpart | pointfloat) exponent
intpart       ::=  digit+
fraction      ::=  "." digit+
exponent      ::=  ("e" | "E") ["+" | "-"] digit+

When Python sees 5., it thinks that the grammar follows [intpart] fraction | intpart "." rule. So, it picks up the next character and finds that it doesn't match the fraction rule. That is why the syntax error is thrown.

You can get around that by

5 .bit_length()

Or enclosing that in brackets like this

(5).bit_length()
like image 122
thefourtheye Avatar answered Oct 17 '22 04:10

thefourtheye


Actually thefourtheye is slightly mistaken in that the reason for syntax error is not that the fraction rule is not matched.

The reason for the syntax error is that that this rule is used to parse it as a floating point:

pointfloat    ::=  [intpart] fraction | intpart "."

The number matches the second form, that has integer part followed by a . - 5. is a valid literal for floating point, and the token stream produced by 5.bit_length produces 2 tokens: 5. (that is, float 5.0) and bit_length; a floating point literal followed by a name is syntax error in python.

It is actually possible to call a float method however, with 2 dots:

>>> 5.0.hex()
'0x1.4000000000000p+2'
>>> 5..hex()
'0x1.4000000000000p+2'

To call the int method, you need to separate the 5 from . to make them parsed as separate tokens.