eval()

eval() 函数是干什么的

eval() 的作用可以先用一句话理解:

eval() 会把“字符串形式的 Python 表达式”当成真正的 Python 表达式来执行,并返回执行结果。

注意这里有两个关键词:

  1. 字符串形式
  2. 表达式

比如:

result = eval("1 + 2 + 3")
print(result)

输出:

6

这里 "1 + 2 + 3" 本来只是一个字符串,但 eval() 会把它当成真正的 Python 表达式:

1 + 2 + 3

然后计算出结果 6


基本语法

eval() 最基础的写法是:

eval(expression)

其中:

expression

通常是一个字符串,这个字符串里面写的是 Python 表达式。

例如:

eval("3 + 5")
eval("10 * 2")
eval("'hello' + 'world'")
eval("[1, 2, 3]")

它们分别相当于执行:

3 + 5
10 * 2
'hello' + 'world'
[1, 2, 3]

eval() 的执行过程

比如这句代码:

x = eval("10 + 20")

程序会这样执行:

第一步,看到字符串:

"10 + 20"

第二步,eval() 去掉字符串外面的引号,把里面的内容当成 Python 表达式:

10 + 20

第三步,Python 计算这个表达式:

30

第四步,把结果赋值给变量 x

x = 30

所以:

print(x)

输出:

30

最小可运行例子

s = "100 + 200"

result = eval(s)

print(result)

输出:

300

这里要注意,s 里面保存的是字符串:

"100 + 200"

但是经过:

eval(s)

以后,它就被当成了真正的计算表达式:

100 + 200

eval() 的几个特点

1. eval() 会返回结果

eval() 不是单纯“执行一下”,它会把表达式的结果返回出来。

例如:

result = eval("3 * 4")
print(result)

输出:

12

所以它常常会配合变量使用:

result = eval(...)

2. eval() 只能执行“表达式”,不能执行普通语句

这是初学者很容易混淆的一点。

表达式是“有结果的代码”。

比如这些是表达式:

1 + 2
"hello"
[1, 2, 3]
len("abc")

它们都有一个结果。

但是下面这些不是表达式,而是语句:

a = 10
if a > 5:
    print(a)
for i in range(3):
    print(i)

所以:

eval("1 + 2")

可以。

但是:

eval("a = 10")

不可以,会报错。

因为赋值语句不是表达式。


3. eval() 可以把字符串转成列表、元组、字典等 Python 对象

例如:

s = "[1, 2, 3]"

result = eval(s)

print(result)
print(type(result))

输出:

[1, 2, 3]
<class 'list'>

这里 " [1, 2, 3] " 本来是字符串,经过 eval() 之后,变成了真正的列表。

再比如字典:

s = "{'name': 'Tom', 'age': 18}"

data = eval(s)

print(data)
print(type(data))

输出:

{'name': 'Tom', 'age': 18}
<class 'dict'>

4. eval() 可以使用当前程序中已经存在的变量

例如:

a = 10
b = 20

result = eval("a + b")

print(result)

输出:

30

因为程序里已经有变量 ab,所以 eval("a + b") 会把字符串里面的 a + b 当成真正的表达式来计算。


eval() 和 input() 经常一起出现

有些题目会这样写:

x = eval(input())

这个写法对初学者来说比较绕,拆开看就清楚了。

假设用户输入:

1 + 2 + 3

代码:

x = eval(input())

执行过程是:

第一步:

input()

接收用户输入,得到的是字符串:

"1 + 2 + 3"

第二步:

eval("1 + 2 + 3")

把这个字符串当成表达式计算。

第三步,得到结果:

6

第四步,赋值给 x

x = 6

所以:

x = eval(input())
print(x)

如果输入:

1 + 2 + 3

输出就是:

6

eval() 和 int(input()) 的区别

这是一个非常重要的区别。

int(input())

n = int(input())

适合用户输入一个整数,例如:

123

它的意思是:

先用 input() 得到字符串:

"123"

再用 int() 转成整数:

123

eval(input())

x = eval(input())

适合用户输入一个 Python 表达式,例如:

1 + 2 * 3

它会把这个输入当成表达式计算,结果是:

7

对比一下:

n = int(input())

如果你输入:

1 + 2 * 3

它会报错,因为 int() 不能把 "1 + 2 * 3" 直接转成整数。

但是:

x = eval(input())

可以计算出结果。


从思路到代码:什么时候会想到用 eval()

假设题目说:

用户会输入一个 Python 表达式,比如:

[1, 2, 3]

或者:

1 + 2 + 3

你需要把它当成真正的 Python 内容来处理。

这时候可以考虑 eval()

思考过程是:

第一步,用户输入的内容一定先是字符串。

s = input()

第二步,如果这个字符串本身就是一个合法的 Python 表达式,可以用 eval() 转换或计算。

value = eval(s)

第三步,再使用得到的结果。

print(value)

完整代码:

s = input()

value = eval(s)

print(value)

eval() 最大的问题:不安全

eval() 很方便,但它有一个非常大的问题:

它会执行字符串里面的 Python 代码。

如果输入内容不是你自己控制的,而是别人输入的,就可能有安全风险。

例如:

eval(input())

如果用户输入的是普通表达式:

1 + 2

还好。

但是如果用户输入的是危险代码,eval() 也可能尝试执行。

所以在真实项目中,通常不建议随便对用户输入使用 eval()

在学习题目中看到 eval(),多数是因为平台已经默认输入是安全的、格式是规定好的。


初学者常见错误与易混点

错误一:以为 eval() 可以执行所有代码

错误理解:

eval("a = 10")

这是不行的。

因为 a = 10 是赋值语句,不是表达式。


错误二:忘记 eval() 的参数通常是字符串

正确:

eval("1 + 2")

不常见写法:

eval(1 + 2)

这就不是把字符串表达式交给 eval() 了。

eval() 主要处理的是字符串形式的表达式。


错误三:把 eval(input()) 和 int(input()) 混为一谈

int(input())

主要用于输入整数。

eval(input())

可以用于输入表达式、列表、元组、字典等 Python 字面量。

例如输入:

[1, 2, 3]

eval(input()) 可以得到真正的列表。


错误四:在真实项目中随便使用 eval()

学习题目里可以见到:

x = eval(input())

但真实项目中要谨慎。

因为用户输入什么,eval() 就可能尝试执行什么。


本节小结

eval() 的核心特点是:

它把字符串形式的 Python 表达式变成真正的 Python 表达式,并返回计算结果。

比如:

eval("1 + 2")

结果是:

3

再比如:

eval("[1, 2, 3]")

结果是真正的列表:

[1, 2, 3]

但要记住两点:

第一,eval() 只能处理表达式,不能处理普通语句。

第二,eval() 有安全风险,不能随便对用户输入使用。


练习

题目:

用户输入一个列表形式的字符串,例如:

[10, 20, 30]

请你把它转换成真正的列表,并输出这个列表的第一个元素。

提示:

先用 input() 接收输入。

然后用 eval() 把字符串转成真正的列表。

最后用下标 [0] 取出第一个元素。

这道题本质上在考什么?

这道题不是让你手动解析多项式,而是在考 Python 里的 eval()

题目给你两样东西:

第一行:

1 4

表示:

x = 1
k = 4

第二行:

x**3 + x**2 + x + 1

表示一个多项式表达式:

P(x) = x**3 + x**2 + x + 1

你的任务是判断:

P(x) == k

如果相等,输出:

True

否则输出:

False

这道题的思考步骤

先不要急着写代码,先把题目翻译成人话。

题目说:

给你一个 x,给你一个 k,再给你一个关于 x 的表达式。你要判断这个表达式在当前 x 的值下,计算结果是不是等于 k

比如样例:

x = 1
k = 4
P = x**3 + x**2 + x + 1

代入 x = 1

1**3 + 1**2 + 1 + 1
= 1 + 1 + 1 + 1
= 4

结果等于 k,所以输出:

True

关键点:eval() 是干什么的?

eval() 的作用是:

把一个“字符串形式的 Python 表达式”当成真正的 Python 表达式来计算。

比如:

s = "1 + 2"
print(eval(s))

输出:

3

注意,s 本来只是一个字符串:

"1 + 2"

但是 eval(s) 会把它当成真正的表达式:

1 + 2

然后计算结果。


为什么这题可以用 eval()?

因为题目第二行直接给了一个合法的 Python 表达式:

x**3 + x**2 + x + 1

它里面用到了变量 x

只要我们提前写好:

x = 1

那么再执行:

eval("x**3 + x**2 + x + 1")

Python 就会用当前变量 x 的值去计算这个表达式。

完整理解是:

x = 1

expression = "x**3 + x**2 + x + 1"

result = eval(expression)

print(result)

输出:

4

因为此时 eval() 看到表达式里面有 x,会到当前代码环境里找变量 x,发现:

x = 1

于是完成计算。


代码怎么写?

这道题最标准的写法是:

x, k = map(int, input().split())

p = input()

print(eval(p) == k)

一行一行解释

第一行:

x, k = map(int, input().split())

假设输入是:

1 4

先看里面:

input()

读入一整行字符串:

"1 4"

然后:

split()

按照空格拆开:

["1", "4"]

再用:

map(int, ...)

把字符串转成整数:

1, 4

最后赋值:

x = 1
k = 4

所以这一句的作用是:读入 xk


第二行:

p = input()

假设输入是:

x**3 + x**2 + x + 1

那么:

p = "x**3 + x**2 + x + 1"

注意,p 现在是一个字符串。


第三行:

print(eval(p) == k)

先计算:

eval(p)

也就是:

eval("x**3 + x**2 + x + 1")

由于前面已经有:

x = 1

所以它会计算:

1**3 + 1**2 + 1 + 1

结果是:

4

然后比较:

4 == k

k = 4,所以:

4 == 4

结果是:

True

最后输出:

True

为什么不用自己拆多项式?

因为题目给的第二行本身就是 Python 能看懂的表达式。

例如:

x**3 + x**2 + x + 1

在 Python 里:

** 

表示乘方。

所以:

x**3

表示:

x 的 3 次方

题目其实就是想让你使用 eval(),而不是自己去解析 x**3x**2+ 这些符号。


最小可运行例子

你可以先在本地试这个:

x = 1
k = 4

p = "x**3 + x**2 + x + 1"

print(eval(p))
print(eval(p) == k)

输出:

4
True

然后再改成正式输入版:

x, k = map(int, input().split())
p = input()

print(eval(p) == k)

这道题的完整思路总结

遇到这种题,可以这样想:

第一步,题目要判断什么?

P(x) == k

第二步,输入给了什么?

x, k

以及一个表达式:

P

第三步,代码怎么做?

先读入 xk

x, k = map(int, input().split())

再读入表达式字符串:

p = input()

然后用 eval() 计算表达式:

value = eval(p)

最后判断:

print(value == k)

所以也可以写成更清楚的版本:

x, k = map(int, input().split())

p = input()

value = eval(p)

print(value == k)

这个版本比一行写法更适合初学者理解。


常见错误

1. 把 ^ 当成乘方

Python 里面乘方不是:

x^3

而是:

x**3

所以题目里的表达式会写成:

x**3 + x**2 + x + 1

2. 忘记把 xk 转成整数

错误写法:

x, k = input().split()

这样得到的是字符串:

x = "1"
k = "4"

后面比较时容易出问题。

正确写法:

x, k = map(int, input().split())

3. 不理解为什么 eval(p) 认识 x

因为前面已经写了:

x = 1

所以当前程序环境里已经有变量 x

eval() 计算表达式:

"x**3 + x**2 + x + 1"

时,它会使用当前的 x 值。


4. 现实开发中不要随便用 eval()

这道题可以用 eval(),是因为 HackerRank 的题目输入是受控的。

但在真实项目中,如果用户输入:

一些危险代码

eval() 可能会直接执行它,所以有安全风险。

所以可以这样记:

在这道题里,eval() 是考点,可以用。

在真实项目里,不要随便对用户输入使用 eval()


练习

题目:

输入:

2 10
x**2 + x + 4

请你判断程序应该输出什么。

提示:

先把 x = 2 代入:

x**2 + x + 4

再看计算结果是否等于 k = 10

题目考点

这道题主要考:

  1. input() 读取一整行字符串
  2. eval() 把字符串当作 Python 表达式执行
  3. 理解 print(2 + 3) 这种输入本身就会产生输出
  4. 不要额外多写一层 print(eval(...))

这题不是算法题,核心是理解:题目输入的内容本身就是一段 Python 表达式,我们只需要让 Python 去执行它。


审题

题目说:

You are given an expression in a line. Read that line as a string variable, such as var, and print the result using eval(var).

意思是:

输入是一行字符串,比如:

print(2 + 3)

这一行看起来像代码,但它其实是从标准输入读进来的字符串。

程序要做的是:

var = input()
eval(var)

关键点在于:输入的内容是 print(2 + 3),它本身就带有 print()

所以执行:

eval("print(2 + 3)")

等价于执行:

print(2 + 3)

输出就是:

5

思路提示

这道题可以按三步想:

第一步,用 input() 读取这一整行内容。

例如用户输入:

print(2 + 3)

程序读到的其实是字符串:

"print(2 + 3)"

第二步,把这个字符串交给 eval()

第三步,注意不要再外面包一层 print(),因为输入里的表达式可能已经包含 print()


完整设计思路

这题代码很短,但容易错在输出方式上。

我们先用:

expression = input()

把输入的一整行保存下来。

如果输入是:

print(2 + 3)

那么 expression 里面存的就是:

"print(2 + 3)"

然后执行:

eval(expression)

Python 会把字符串内容当作 Python 表达式执行。

也就是说:

eval("print(2 + 3)")

会触发里面的 print(2 + 3),所以屏幕上会输出:

5

代码实现

if __name__ == '__main__':
    expression = input()
    eval(expression)

也可以写得更短:

eval(input())

对于初学者,我更建议先写第一种,因为更清楚:

expression = input()
eval(expression)

这样你能明显看到:先读入字符串,再执行字符串。


为什么不是这样写?

很多人会下意识写成:

print(eval(expression))

这在本题里通常是错的。

因为如果输入是:

print(2 + 3)

那么:

eval("print(2 + 3)")

会先输出:

5

但是 print(2 + 3) 这个函数执行完之后,返回值是 None

所以如果你写:

print(eval("print(2 + 3)"))

实际过程是:

第一步,里面的 print(2 + 3) 输出:

5

第二步,eval(...) 的返回值是 None

第三步,外层 print(None) 又输出:

None

最终就会变成:

5
None

这就和题目要求不一致了。

所以本题只写:

eval(expression)

运行演示

假设输入是:

print(2 + 3)

程序执行:

expression = input()

此时:

expression = "print(2 + 3)"

然后执行:

eval(expression)

等价于执行:

print(2 + 3)

所以输出:

5

方法总结

这类题下次可以这样判断:

如果题目说:

输入的是一段 Python 表达式,让你用 eval() 执行

那么基本套路就是:

expression = input()
eval(expression)

重点不是循环、判断、列表,而是理解:

input()

读到的是字符串。

eval()

会把这个字符串当成 Python 表达式执行。

本题最容易错的地方是:不要写成 print(eval(input()))


练习

请思考下面这道类似小练习。

输入一行 Python 表达式:

len("hello")

要求程序执行这个表达式,并打印执行结果。

提示:

这次输入里面没有自带 print(),所以你需要思考:应该写 eval(input()),还是 print(eval(input()))

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇