7

Earlier I heard that eval(input(a)) will convert a string automatically to int, but if i code

age = eval(input("enter age"))

during input i type in 01 it is an error, but when i code

age = int(input("enter age"))

01 as input works perfectly. Why is it?

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Cheang Wai Bin
  • 181
  • 1
  • 1
  • 9
  • 2
    If you use `eval` you could end up with something disastrous like `eval("__import__('os').system('rm -rf $HOME')")` (which would delete files in your home directory, DON'T actually try this...) – Dietrich Epp Aug 25 '17 at 12:43

2 Answers2

8

eval evaluates the python expression. In python 3, numbers starting by 0 aren't allowed (except for 0000, see Why does 000 evaluate to 0 in Python 3?). In python 2, those are interpreted as octal (base 8) numbers. Not better... (python 3 base 8 now uses exclusively Oo prefix)

int performs a string to integer conversion, so it cannot evaluate a complex expression (that you don't need), but isn't subjected to this leading zero syntax.

Another nice feature is that you can check if the entered expression is an integer by using a simple and qualified try/except block:

while True:
   try:
       age = int(input("enter age"))
       break
   except ValueError:
       print("Retry!")

(with eval you would have to protect against all exceptions)

Advice: use int, because it's safer, doesn't have security issues (eval can evaluate any expression, including system calls and file deletion), and suits your purpose perfectly.

Note: the above code is still unsafe with python 2: input acts like eval. You could protect your code against this with the simple code at the start of your module:

try:
    input = raw_input
except NameError:
    pass

so python 2 input is not unreachable anymore and calls raw_input instead. Python 3 ignores that code.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • 5
    Not only is it safer - it'll also fail so you can re-try or whatever if an `int` can't be produced - rather than produce *something* that isn't one... – Jon Clements Aug 25 '17 at 12:38
  • Can i understand it as `eval` is use to perform much complex expression while `int` only convert a string to integer? What are octal and zero syntax? – Cheang Wai Bin Aug 25 '17 at 12:49
  • 1
    eval evaluates any python code. int tries to convert any type to integer (float, bool, string ...). you got it. Octal is base 8 representation: in python 2: `010 == 8` (like binary or hex). In python 3 that doesn't work anymore. – Jean-François Fabre Aug 25 '17 at 12:50
6

eval() is used to verify an expression. On number is considered an expression, except octal numbers (numbers that start with 0). int() handles string to integer conversion. There are many reasons why you should avoid using eval(). Just keep in mind:

  • Python 2.x

    x = raw_input('Enter number here: ') 
    
  • Python 3.x

    x = input('Enter number here: ') 
    
  • Python 2.x
    Security risk:

    x = input('Enter number here: ') 
    
  • Python 3.x
    Security risk:

    x = eval(input('Enter number here: ')) 
    

Also, keep in mind that eval() has the potential to run code, which could cause a huge security risk. I suggest not using it unless you clearly know what you're doing or it could compromise your application.

fractals
  • 816
  • 8
  • 23
Francisco Flores
  • 290
  • 2
  • 16
  • What kind of security risk? i'm new to programming – Cheang Wai Bin Aug 25 '17 at 12:52
  • You can check out many different examples and explanations [here](https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) – Francisco Flores Aug 25 '17 at 13:13
  • you can for example `import subprocess; eval("subprocess.run('whatever program I like')")` that is very dangerous and the user should not probably be allowed to do it. Hence, you should pass only 100% trustworthy input to `eval`. – user1747134 Aug 25 '17 at 13:29