Python Zelle book使用eval(),是不是错了?

2024-06-28 19:14:34 发布

您现在位置:Python中文网/ 问答频道 /正文

请注意:这不是关于eval()的使用,而是关于一本书的潜在质量(或缺乏质量)。所以在Python中已经有无数关于eval()的线程。在

冒着招致SO的愤怒和反对票,我还是决定问这个问题,以防万一。请容忍我。我试过Google和它自己来解决这个问题(你会看到的),但是什么也没有。不过,我可能是瞎子。在

这个问题是关于臭名昭著的eval()函数的使用。在

有一本比较有名的书(如你所见,得到了很好的评论):johnzelle:http://www.amazon.com/Python-Programming-Introduction-Computer-Science/dp/1590282418/ref=pd_sim_b_3

从技术上讲,这是一本使用Python作为编程语言的CS1书籍。公平地说,这样做减轻了作者的一些责任(“嘿,我想在这里教你一些宽泛的东西,而不是所有这些语法和安全细节”),但当我开始阅读它时,我注意到,在第一个例子中,使用

x = eval(input("Enter your number: "))

其中x应该是int,因此我们需要将用户输入转换为int

我使用的是Python2.7.4,这本书是关于Python3的,所以我从一开始就在print()和input()以及eval()中遇到了很多问题,因此我不得不做一些研究以使示例生效。在我的研究过程中,我读过无数关于Python中eval()的意见(主要是在这里),这些意见归结为它几乎总是不好、存在安全风险、不必要的技术开销等等。用户的问题要复杂得多(有一个关于在wxPython项目中使用eval()),所以我不能保证我的案例和他们的案例完全相似,但是仍然。。。在

所以,我承认,我对这本书还不太深入,但我已经到了这样一个地步:稍后,作者解释了eval()的用法,而没有提到eval()的争议性质。他基本上说了我刚才说的:我们需要x最终成为int,所以这里有一个方便的方法。他似乎一直在用它。在

我的问题是:如果一个作者从一开始就犯了这样的错误(或者这不是一个错误?这本书值得我学习吗?我相信Zelle先生是一位伟大的CS老师,这也说明了这一点,但不管他是否愿意,人们仍然会从他的书中学习Python,除了学习算法和编程艺术。那么,从一本对Python社区中一个看似普遍的问题保持沉默的书中学习Python值得吗?我不想让泽尔先生成为一个Python黑客,揭开它的所有秘密,但像这样的小细节可以成就或毁掉一个自学成才的人。你对这份学习材料有什么建议?在

另一方面,让我从一开始就做大量的研究和实验(不知不觉地)是相当酷的:-)

谢谢你!在


Tags: 用户inputso错误evalgoogle质量作者
3条回答

是的,错了。但我想我知道为什么会在里面。在

很多人在python2.x中使用input(),这是一个非常不幸的命名函数,因为它不仅读取输入,还计算它。转换器2to3input()的每次使用转换为eval(input()),如您所见:

$ cat test.py
x = input("Enter your number: ")

$ 2to3 test.py
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: Refactored test.py
--- test.py     (original)
+++ test.py     (refactored)
@@ -1 +1 @@
-x = input("Enter your number: ")
+x = eval(input("Enter your number: "))
RefactoringTool: Files that need to be modified:
RefactoringTool: test.py

所以我想这只是有点草率。来自亚马逊的描述:

This is the second edition of John Zelle's Python Programming, updated for Python 3.

我认为有人在所有代码示例上运行2to3,而没有对输出进行足够彻底的检查。所以,是的,在python2.x中使用input()是错误的,在没有检查输出的情况下使用2to3也是错误的。在

既然eval在您给出的示例中是如此的不恰当和不必要,我肯定会怀疑本书其他部分的安全性。作者是否会建议将用户输入的字符串附加到SQL查询中?在

我认为找到作者的电子邮件地址并直接询问他是值得的。在

作为这本书的作者,让我来谈谈这个问题。在

书中eval的使用很大程度上是从python2到python3转换的一个历史产物(尽管在python2中输入的使用中也存在相同的“缺陷”)。我很清楚在生产代码中使用eval的危险性,因为输入可能来自不可信的来源,但这本书不是关于基于web的系统的生产代码,而是关于学习一些CS和编程原理。书中没有任何东西可以被远程视为生产代码。我的目标始终是使用最简单的方法来说明我要表达的观点,eval有助于做到这一点。在

我不同意群众在任何情况下都宣称邪恶。对于只由编写者运行的简单程序和脚本来说,它非常方便。在这种情况下,这是完全安全的。它允许简单的多个输入和表达式 输入。在教学上,它强调表达评价的概念。Eval揭示了解释语言的所有力量(和危险)。我一直在我自己的个人程序中使用eval(不仅仅是在Python中)。事后看来,我完全同意我应该讨论eval的潜在风险;这是我在课堂上经常做的事情。在

底线是这本书有很多改进的方法(总是有的)。我不认为使用eval是一个致命的缺陷;它适用于所示程序的类型和这些程序出现的上下文。我不知道在本书中使用Python的方式还有其他“不安全性”,但是应该提醒您(正如序言所解释的那样),在许多地方,代码并不完全是“Python”的

相关问题 更多 >