Python中eval("input()")与eval(input())的区别

4

我正在尝试以下函数:

x = eval(input())

输入123并将变量x的类型设置为int时,它可以正常工作:

In [22]: x=eval(input("enter:"))
enter:123
In [24]: print(type(x))
<class 'int'>

但是当输入为abcd时,它会抛出错误:

In [26]: x=eval(input("enter:"))
enter:abcd
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-26-fb0be0584c85> in <module>()
----> 1 x=eval(input("enter:"))

<string> in <module>()

NameError: name 'abcd' is not defined

同时,当我将代码修改为以下内容时:
x=eval('input()')

它运行良好:

In [27]: x=eval('input("enter:")')
enter:abcd

In [28]: print(x)
abcd

但是当输入为123时,x的类型为str而不是int

In [30]: x=eval('input("enter:")')
enter:123

In [31]: print(type(x))
<class 'str'>
2个回答

6

eval是一个评估代码的函数。 input从用户输入获取字符串。因此:

  • eval(input())评估用户输入的任何内容。如果用户输入123,结果将是一个数字;如果他们输入"foo",则结果将是一个字符串;如果他们输入?wrfs,则会引发错误。

  • eval("input()")评估字符串"input()",这导致Python执行input函数。这要求用户输入一个字符串(仅此而已),因此123将成为字符串"123"?wrfs将成为字符串"?wrfs""foo"将成为字符串'"foo"'(!)。

可能让差异显而易见的第三个版本:eval(eval("input()"))eval(input())完全相同。


感谢L3viathan的回答,但我仍然有些困惑。为什么Python不像对待123一样对待abcd呢?我的意思是abcd应该自动转换为字符串。为什么我们必须明确地给出"abcd"而不是像普通的input()一样只输入abcd呢? - Nikhil Chhabria
因为abcd不是一个定义过的名称。当你在Python代码中使用abcd时,它将被视为变量、函数等。要将其转换为字符串,需要用双引号括起来。在Python代码中有效的内容,在eval()中也是有效的。为什么Python应该自动将abcd转换为字符串呢?如果你想要一个字符串,为什么要使用eval()呢? - L3viathan
有没有一种方法可以接收来自用户的任何类型的输入,无论是int、string、list还是dictionary?我现在知道eval(input())可以很好地处理这种情况,前提是输入是用引号括起来的。有没有办法在不提供引号字符串的情况下处理其他对象类型的场景? - Nikhil Chhabria
@NikhilChhabria 那么你如何输入字符串“123”呢?此时完全是凭猜测。当然,你可以做一些启发式处理,但我认为这并不聪明。 - L3viathan

0

与其关注eval(“input()”)eval(input())的差异,不如专注于它们的主要相似之处:你都不应该使用它们!

我不知道在Python 3中eval(input())这个用法是从哪里来的,可能是Python 2用户误解了使用raw_input()而引入的问题,但是应避免使用它!

在这种情况下,正确的做法是:如果你想要一个str,那么使用:

x = input()

如果你想要一个 int,那么可以这样做:

x = int(input())

但是停止使用eval(),因为这会让潜在用户滥用您的程序:

>>> x = eval(input('enter: '))
enter: __import__("os").system("rm *")
>>> 

请勿在家中或工作场所尝试此操作!

如果您想要输入常量Python数据结构,可以尝试使用ast模块中的literal_eval()函数:

>>> from ast import literal_eval
>>> my_dict = literal_eval(input('enter dict: '))
enter dict: {'a': 1, 'b': 2, 'c': 3}
>>> my_dict
{'a': 1, 'b': 2, 'c': 3}
>>> type(my_dict)
<class 'dict'>
>>>  

但仍需小心!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接