1

For the code below:

command = '\'{:.' + str(3) + 'f}\'.format(' + str(12.6543423) + ')'

print(command)
print('{:.3f}'.format(12.6543423))
print(exec(command))

Expected results:

'{:.3f}'.format(12.6543423)
12.654
12.654

Actual results:

'{:.3f}'.format(12.6543423)
12.654
None

Please can someone tell me what I'm doing wrong and how to fix it? I'm both trying to write a number rounding function and trying to understand the exec command.

Mauro Baraldi
  • 6,346
  • 2
  • 32
  • 43
Jake Levi
  • 399
  • 2
  • 4
  • 12

5 Answers5

9

Or don't use exec or eval at all. Use the features format offers:

>>> '{:.{}f}'.format(12.6543423, 3)
12.654
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • Ah, thank you - wasn't aware that you could have curly brackets within curly brackets, probably should have tried that first. Thanks. Even so, I'm keeping the current answer ticked, because I was also curious to learn about eval() and exec(). – Jake Levi Nov 05 '14 at 15:02
  • 2
    @JakeLevi learning about eval and exec is good. One of the most important things to learn about them is that they are really really blunt instruments that you almost never need. – Ned Batchelder Nov 05 '14 at 15:24
0

Use eval() instead of exec() to get the result returned by a expression.

Lynn
  • 10,425
  • 43
  • 75
  • Use [`ast.literal_eval`](https://docs.python.org/2/library/ast.html?highlight=ast.literal_eval#ast.literal_eval) instead [`eval`](https://docs.python.org/2/library/functions.html?highlight=eval#eval) – Mauro Baraldi Nov 05 '14 at 12:35
  • @MauroBaraldi: did you try `literal_eval`? It won't work for this case, because `literal_eval` won't invoke `format` for you. It won't call any functions, that's the whole point, to avoid code execution. – Ned Batchelder Nov 05 '14 at 15:05
0

Use eval.

>>> eval('\'{:.' + str(3) + 'f}\'.format(' + str(12.6543423) + ')')
'12.654'
Vishnu Upadhyay
  • 5,043
  • 1
  • 13
  • 24
  • 1
    Use [`ast.literal_eval`](https://docs.python.org/2/library/ast.html?highlight=ast.literal_eval#ast.literal_eval) instead [`eval`](https://docs.python.org/2/library/functions.html?highlight=eval#eval) – Mauro Baraldi Nov 05 '14 at 12:35
  • @MauroBaraldi Concatenation using + isn't included within that,from the doc *The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.* and if i am wrong then help me in that. I would love to know. – Vishnu Upadhyay Nov 05 '14 at 12:47
  • 1
    The `+` operation is not a "feature" of eval. Python first concatenates the strings and only then passes a single string to eval. That is of course the case with all function calls (in every programming language)... – sebastian Nov 05 '14 at 12:54
  • @MauroBaraldi: did you try `literal_eval`? It won't work for this case, because `literal_eval` won't invoke `format` for you. It won't call any functions, that's the whole point, to avoid code execution. – Ned Batchelder Nov 05 '14 at 15:04
0

or you can use exec

command = '\'{:.' + str(3) + 'f}\'.format(' + str(12.6543423) + ')'
print(command)
mycode = """print('{:.3f}'.format(12.6543423))"""

print('{:.3f}'.format(12.6543423))
exec(mycode)
eivl
  • 148
  • 9
  • it does not. i would also use eval() instead. but it is still usable with exec(). There is in my opinion a lot of confusion regarding exec, also some changes from python 2 and 3. – eivl Nov 05 '14 at 13:22
0

You are confusing exec and eval:

In [27]: command = 'print'+'('+'\'{:.' + str(3) + 'f}\'.format(' + str(12.6543423) + ')'+')'

In [28]: exec(command)
12.654
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321