[Tutor] Count for loops

eryk sun eryksun at gmail.com
Wed Apr 12 01:15:25 EDT 2017


On Wed, Apr 12, 2017 at 3:40 AM, boB Stepp <robertvstepp at gmail.com> wrote:
>
> I have to say I am surprised by this as well as the OP.  I knew that
> str() in general makes a nice printable representation

The single-argument str() constructor calls the object's __str__
method (or __repr__ if __str__ isn't defined). In Python 3,
float.__str__ and float.__repr__ behave the same. They use as many
digits as is required to round trip back to the float value exactly.
That's up to 17 digits.

    >>> str(1.2345678901234567)
    '1.2345678901234567'
    >>> str(1.)
    '1.0'

In Python 2, float.__str__ uses up to 12 digits:

    >>> str(1.2345678901234567)
    '1.23456789012'

> realize that using str() on an arbitrarily typed in "float-like" value
> would convert the typed in value to a normal float's max precision.

For a literal floating-point value in source code, the compiler
(component of the interpreter) first parses a NUMBER node:

    >>> e = parser.expr('3.14159265358979323846264338327950288419716939')
    >>> p = parser.st2list(e)
    >>> while p[0] != token.NUMBER:
    ...     p = p[1]
    ...
    >>> p
    [2, '3.14159265358979323846264338327950288419716939']

Next it transforms this concrete syntax tree into a abstract syntax tree:

    >>> a = ast.parse('3.14159265358979323846264338327950288419716939',
    ...               mode='eval')
    >>> ast.dump(a)
    'Expression(body=Num(n=3.141592653589793))'

    >>> a.body.n
    3.141592653589793
    >>> type(a.body.n)
    <class 'float'>

You see above that the AST transforms the NUMBER node into a Num node
that references a float object. The value of the float is the closest
possible approximation of the source code literal as a
double-precision binary float.

If the compiler instead used Decimal objects, then it could retain all
of the literal's precision. Double-precision binary floats are fast
and efficient by virtue of hardware support, but that's not a
compelling reason in Python. Maybe some future version of Python will
switch to using Decimals for floating-point literals.

The final step is to compile this AST into bytecode and create a code
object. The float value is referenced in the code object's co_consts
attribute:

    >>> c = compile(a, '', 'eval')
    >>> c.co_consts
    (3.141592653589793,)

The code in this case is simple; just load and return the constant value:

    >>> dis.dis(c)
      1           0 LOAD_CONST               0 (3.141592653589793)
                  3 RETURN_VALUE

    >>> eval(c)
    3.141592653589793


More information about the Tutor mailing list