2013-04-14 7 views
7

ご注意:これはeval()の使用に関するものではなく、使用され、教えられている本の潜在的な品質(またはその不足)に関するものです。したがって、Pythonではeval()について既に数多くのスレッドがあります。 SOの怒りとdownvotesを招待することを危険にさらすPython - Zelleブックでeval()を使用していますが、間違っていますか?

は、私はそれにもかかわらず念のために、この質問をすることを決めました。私と一緒に抱きしめてください。私はこの特定の質問のためにGoogleとSO自体を試してきましたが(あなたが見るように)、何も得られませんでした。私は盲目になるかもしれない。

この質問は、悪名高いeval()関数の使用についてです。 http://www.amazon.com/Python-Programming-Introduction-Computer-Science/dp/1590282418/ref=pd_sim_b_3

は技術的には、それはプログラミング言語としてPythonを使用していますCS1本です:ジョン・Zelleによって比較的よく知られている(とよく見直し、あなたが見ることができるように)本があり

。十分な意味では、そのようなものは著者の肩からの責任を取り除いています(「やあ、ここでは広範なものを教えようとしていますが、これらの構文とセキュリティの詳細すべてを教えようとしていません」)非常に最初の例で、xは整数であるべきであり、従って、我々は、INTにユーザ入力を変換する必要が

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

の使用。

私はPython 2.7.4を使用しています。この本はPython 3に関するものなので、print()とinput()とeval()の最初からかなりの問題に直面していました。例を得るための研究私の研究の過程では、Pythonのeval()に関する多くの意見を読んだことがあります。ほとんどの場合、セキュリティリスク、不必要な技術的オーバーヘッドなどがあります。ユーザの質問は、(wxPythonのプロジェクトを行う際にeval()を使用して約があった)多くの精巧だったので、私は私の場合、その例間の総類似性を保証することはできませんが、それでも...

だから私はあまりにも本書には遠すぎるわけではないが、もう少し後で、論者の本質に言及していないeval()の使用法について説明したところに達した。彼は基本的に私が言ったことを言った:私たちは最終的にintである必要があるので、ここでそれを行う便利な方法です。そして彼はそれをずっと使っているようだ。 、右の初めから、著者は、このような間違いをした場合(?または、それは間違いではありません、私はここで何かが足りない可能性があります)、それはから学ぶ価値がある本です:

私の質問はこれですか?私はZelle氏がCSの素晴らしい教師だと信じていますが、彼が望んでいるかどうかに関わらず、人々はアルゴリズムとプログラミング技術に加えて、彼の本からPythonを学びます。だから、Pythonコミュニティでこのような一見普遍的な問題を黙っている本からPythonを学ぶ価値はあるのだろうか? Zelle氏がPythonのハッカーであり、その秘密をすべて明らかにすることは望んでいませんが、これらのような細部は自己教える/自己学習する人を作り、壊すことはありません。この学習教材に関してあなたのアドバイスは何ですか?

P.S.一方、(無意識のうちに)私は研究と実験のかなりのビットを行う作ることは最初から

:-)かなりクールですありがとうございます!

+0

私はevalがJavaScriptの中で悪いと思った。 –

+5

@JasonSperskeどこでも悪い – jamylak

+4

int()の代わりにeval()が誤っているようだ。 –

答えて

9

問題の本の著者として、私はこの問題を勘案してください。

本のevalの使用は、Python 2からPython 3への変換の歴史的な成果物です(Python 2での入力の使用にも同じ "欠陥"があります)。私は、入力が信頼できないソースから来るかもしれない生産コードでevalを使用する危険性を十分に認識していますが、この本はWebベースのシステムの生産コードではありません。それはいくつかのCSとプログラミングの原則を学ぶことです。この本には、実際には生産コードとは考えられないものは何もありません。私の目標は、私が作ろうとしているポイントを説明することができる最も単純なアプローチを使用することです.evalはこれを行うのに役立ちます。

私はすべての文脈でeval evilを宣伝する観衆に同意しません。彼らの作家だけが実行している簡単なプログラムやスクリプトの場合は、非常に便利です。この文脈では、それは完全に安全です。単純な複数の入力と式を と入力することができます。教育的には、表現評価の概念を強調している。 Evalは、解釈された言語の力(そして危険)をすべて公開します。私は私自身の個人的なプログラム(Pythonだけでなく)でevalを使っています。後見では、私はevalの潜在的なリスクについての議論を含めるべきであることに絶対に同意します。これは私のクラスでいつもやっていることです。

結論は、この本が改善される方法がたくさんあることです(いつもあります)。私はevalを使うのは致命的な欠陥だとは思わない。図示されているプログラムのタイプおよびそれらのプログラムが現れるコンテキストに適している。Pythonが本書で使われる方法で他の "不安"があることは認識していませんが、コードが正確に "Python"ではないところがたくさんあることを警告する必要があります。

+5

これに対応するためにStackOverflowに参加しましたか?うわー、お元気です、正直にあなたが公式に応答して、あなたの本が好奇心をそそられました(私はPythonを学んでいます)。私はいつもこのサイトの作者が仲間のプログラマーを魅了しているのを見てうれしいです。私はこのサイトの離れていることが、より良い作者と教師になることを願っています。尊敬と誠意を持って、Stack Overflowへようこそ。 –

+0

私は最高の本は著者がアクセス可能なものだと思います。だから、おそらく、あなたの3番目の追加はこの点でより良いでしょう。つまり、私はeval()の使用法が "pythonic"問題であるとあなたに同意しない。私は本の読者が物事を正しく行うかどうかを学ぶかどうかという基本的な問題だと考えています。私はあなたのスクリプトが持っているセキュリティの脆弱性について言及すべきであること、あるいはPython 2のコードから素早く変換された歴史に苦しまないPython 3のコードを書く方が良いことに同意します。 – Kaydell

2

はいは、代わりにevilと警告する必要があります。絶対に必要な場合を除き、絶対に使用しないでください。この場合、代わりにint()を使用するのは直感的です。さらに読みやすくなります。また、あなたが本当に持っていたのであれば、ast.literal_evalを使用することもできます(名前が示すようにリテラルのみを評価するので、悪意のあるコードを実行することはできません)が、実際には安全ですが、必要はありません。この場合はeval()となります。

+0

ありがとう!私の質問は、初心者が理論的に完全に信頼しなければならない、尊敬されている教授のCS-Pythonの本の中にそのようなコードが存在しているというあなたの意見についてのもう少しです。それは悪い本か、彼が作ったちょっとした間違いですか?それは材料の質について他にはっきり言ってはいけませんか? – Leo

4

evalは、あなたが与えた例ではあまりにも不十分であり、不要なので、本の他の部分の安全性には疑いがあります。著者は、ユーザが入力した文字列をSQLクエリに追加することを提案していますか?

私は、著者の電子メールアドレスを見つけて、彼にそれについて直接質問する価値があると思います。

+0

ありがとう!私はそれをすることを考えましたが、誰がCS教授に質問するのですか?私は自分のベルトの下で非常に少数のプロジェクトを持つただの愛好家のセミプログラマーです。大学の学位は、コンピュータや技術とはまったく関係がありません。私がここではなく、彼ではないということははるかに可能性が高い。それは単なる奇妙なことです...大学で使われている本、確かに誰かがこの質問を今でも尋ねてきましたが、Googleは何もしません。 – Leo

+0

@Gleb - しかし、あなたは自分の知識に基づいて 'eval'の使用に疑問を呈していません。 [あなたはこれだけではありません](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html)、ちょうど行くと尋ねる。あなたは何を失いましたか? – root

+1

私は著者の電子メールを見つけて、これについて彼に尋ねました。誰もが彼は素晴らしい人だと言ってくれてうまくいけば、彼は私に怒らないだろう:-)初心者がセキュリティを気にするべきではないとしても、この非常にウェブサイトのようなどこかでコードのスニペットを提出することは残念だ。 ..うん、嫌いじゃない、もちろん、誰があなたにこのように教えてくれたの?0_o?! "という行に沿った批判の弾幕。 – Leo

3

まあ、このような方法でeval()とinput()を組み合わせることは、初歩的な、しかし非常に有害な「シェル」を作ります。 私は本を読んでいないが、私はそれを塩の穀物で取るだろう。悪い習慣ではなく、ひとつの致命的な機能の組み合わせを実装しています。

5

はい、間違っています。しかし、私はそれがなぜそこにあるのか分かっていると思う。

多くの人がPython 2.xでinput()を使用しています。これは入力を読み込むだけでなく、評価するため非常に不幸なことです。あなたが見ることができるように、コンバータ2to3は、eval(input())から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 

だから私の推測では、それはほんの少しずさんであるということです。アマゾンの記述から:

これは、Python 3

のために更新され、ジョンZelleのPythonプログラミングの第二版である私は誰かが徹底的に十分な出力を確認することなく、コードサンプルのすべての2to3を走ったと思います。だから、input()をPython 2.xで使うのは間違いで、出力を確認せずに2to3を使うのは間違いです。

+2

私はちょっとした調査であなたが正しいと思いますが、問題は著者が実際にeval()の使用についてコメントしていないことです。このエディションの唯一の目的(冒頭に漠然と記載されている)がPython 3である場合、そのPython 3は、盲目的な更新ではなく、有効なPython 3でなければなりません。 Python 3を作成する理由は、このような問題を解決することにあります。私はどの本でもそれを考慮に入れるべきだと思う。 – Leo

+2

raw_input()を使用していなかったので、作者の間違いは初版にありました –

関連する問題