Problem
In the book that I am reading on Python, it keeps using the code eval(input(‘blah’))
I read and understand the documentation, but I’m still not sure how it affects the input() function.
What exactly does it do? Could someone please explain?
Asked by Billjk
Solution #1
The eval function allows a Python program to execute Python code within another Python program.
Example of eval (interactive shell):
>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1
Answered by BYS2
Solution #2
The function eval() converts a string to code. Because a user can use this as an option to run code on the computer, several individuals have warned you against using it. Someone could type os.system(‘rm -R *’) into input() if you had eval(input()) and os imported. This would erase all your files in your home directory. (Assuming you’re using a Unix-based system.) The use of eval() is a security flaw. If you need to convert strings to different formats, look for tools that can do so, such as int ().
Answered by CoffeeRain
Solution #3
There are a lot of nice answers here, but none of them explain how to use eval() with its globals and locals kwargs, i.e. eval(expression, globals=None, locals=None) (see docs for eval here).
These can be used to restrict the functions that the eval function can access. For example, if you start a new Python interpreter, the locals() and globals() functions will be identical and look like this:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
There are certainly functions in the builtins module that can cause serious system damage. However, anything and anything we don’t want to be available can be blocked. Let’s have a look at an example. Let’s say we wish to create a list that represents a domain of a system’s available cores. I have 8 cores, so I’d like a list that starts with [1, 8].
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
Similarly, all of __builtins__ are accessible.
>>>eval('abs(-1)')
1
Ok. So there we see one function we want exposed and an example of one (of many that can be much more complex) method that we do not want exposed. So let’s put a stop to everything.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
We’ve basically disabled all of the __builtins__ functions, providing a measure of security to our system. We can now begin to add back in the functions that we do want exposed.
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
Now we have the cpu count function, but anything we don’t want is still blocked. This is, in my perspective, extremely powerful and, based on the scope of the other replies, certainly not a common implementation. There are various applications for something like this, and as long as it is managed properly, I believe eval may be utilized to great use.
N.B.
Something else that is cool about these kwargs is that you can start to use shorthand for your code. Let’s say you use eval as part of a pipeline to execute some imported text. The text doesn’t need to have exact code, it can follow some template file format, and still execute anything you’d like. For example:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
Answered by Grr
Solution #4
In Python 2.x, input(…) is similar to eval(raw input(…)), however raw input was renamed input in Python 3.x, which I believe caused your confusion (you were probably looking at the documentation for input in Python 2.x). Additionally, in Python 3.x, eval(input(…)) would work well, but in Python 2, it would generate a TypeError.
In this scenario, the string returned from input is coerced into an expression and interpreted using eval. This is often thought to be unethical.
Answered by zeekay
Solution #5
Perhaps a deceptive example of reading and interpreting a line.
Try typing “1+1” into eval(input()) – this should print 2. Eval is a function that evaluates expressions.
Answered by hburde
Post is based on https://stackoverflow.com/questions/9383740/what-does-pythons-eval-do