Python - Zelle Buch verwendet eval (), ist es falsch?

7

BITTE BEACHTEN SIE: Dies ist NICHT die Verwendung von eval (), es geht um die potentielle Qualität (oder das Fehlen davon) eines Buches, in dem es verwendet und gelehrt wird. SO hat bereits unzählige Threads über eval () in Python.

Ich habe riskiert, den Zorn und die Kritik von SO einzuladen, aber ich habe trotzdem beschlossen, diese Frage zu stellen, nur für den Fall. Bitte bei mir tragen. Ich habe Google und SO selbst für diese spezielle Frage ausprobiert (wie Sie sehen werden) und nichts bekommen. Ich könnte jedoch blind sein.

In dieser Frage geht es um die notorische eval () -Funktion.

Es gibt ein relativ bekanntes (und gut rezensiertes) Buch von John Zelle: Ссылка

Technisch handelt es sich um ein CS1-Buch, das Python als Programmiersprache verwendet. Gut genug, diese Art von Verantwortung entzieht den Schultern des Autors ("Hey, ich versuche dir hier etwas Breites beizubringen, nicht alle diese Syntax- und Sicherheitsdetails"), aber als ich anfing zu lesen, bemerkte ich es buchstäblich Das erste Beispiel, die Verwendung von

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

wobei x ein int sein soll und somit Benutzereingaben in int umgewandelt werden müssen.

Ich benutze Python 2.7.4 und das Buch handelt von Python 3, so dass ich von Anfang an ziemlich viele Probleme mit print () und input () und eval () hatte und etwas recherchieren musste um die Beispiele zum Laufen zu bringen. Im Zuge meiner Recherchen habe ich in Python (meistens hier auf SO) unzählige Meinungen über eval () gelesen, die darauf hinauslaufen, dass es fast immer schlecht ist, ein Sicherheitsrisiko, ein unnötiger technischer Overhead und so weiter. Die Fragen der Benutzer waren viel ausgeklügelter (es gab einen über die Verwendung von eval () bei einem wxPython-Projekt), also kann ich nicht für die totale Ähnlichkeit zwischen meinem Fall und ihren Fällen bürgen, aber trotzdem ...

Also, ich gebe zu, ich bin nicht zu weit in das Buch hinein, aber ich habe den Punkt erreicht, an dem der Autor etwas später den Gebrauch von eval () ohne jeglichen Hinweis auf seine umstrittene Art erklärte. Er hat im Grunde gesagt, was ich gerade gesagt habe: Wir brauchen x, um schließlich ein Int zu sein, also ist hier ein praktischer Weg, das zu tun. Und er scheint es immer wieder zu benutzen.

Meine Frage ist folgende: Wenn ein Autor von Anfang an einen solchen Fehler macht (oder ist es kein Fehler? Ich verpasse hier etwas), ist es ein Buch, von dem es sich zu lernen lohnt? Ich glaube, Herr Zelle ist ein großartiger CS-Lehrer, und das zeigt, aber ob er es will oder nicht, die Leute werden Python auch noch aus seinem Buch lernen, zusätzlich zu Algorithmen und der Kunst des Programmierens. Ist es also wert, Python aus einem Buch zu lernen, das über ein so scheinbar universelles Problem in der Python-Community schweigt? Ich möchte nicht, dass Herr Zelle ein Python-Hacker ist und alle seine Geheimnisse aufdeckt, aber kleine Details wie diese können jemanden, der sich selbst unterrichtet oder selbst lernt, zum Bösen machen. Was wird Ihr Rat in Bezug auf dieses Lernmaterial sein?

P.S. Auf der anderen Seite ist es ziemlich cool, mich (unwissentlich) von Anfang an zu forschen und zu experimentieren :-)

Danke!

    
Leo 14.04.2013, 04:24
quelle

5 Antworten

9

Lassen Sie mich als Autor dieses Buches zu diesem Thema etwas sagen.

Die Verwendung von eval im Buch ist größtenteils ein historisches Artefakt der Konvertierung von Python 2 zu Python 3 (obwohl der gleiche "Fehler" bei der Verwendung von Eingaben in Python 2 existiert). Ich bin mir der Gefahren bewusst, die die Verwendung von eval im Produktionscode birgt, wenn die Eingabe von einer nicht vertrauenswürdigen Quelle kommen kann, aber im Buch geht es nicht um Produktionscode für ein webbasiertes System; Es geht darum, einige CS- und Programmiergrundsätze zu lernen. Es gibt wirklich nichts in dem Buch, das als Produktionscode entfernt betrachtet werden könnte. Mein Ziel ist es immer, den einfachsten Ansatz zu verwenden, der es mir ermöglicht, den Punkt zu veranschaulichen, den ich versuche zu machen, und eval hilft dabei.

Ich stimme nicht mit der Menge überein, die Eval Evil in allen Kontexten verkündet. Es ist sehr praktisch für einfache Programme und Skripte, die nur von ihrem Schreiber ausgeführt werden. In diesem Zusammenhang ist es vollkommen sicher. Es ermöglicht einfache Mehrfacheingaben und Ausdrücke als Eingang. Pädagogisch betont es das Konzept der Ausdrucksbewertung. Eval deckt die ganze Macht (und Gefahr) einer interpretierten Sprache auf. Ich benutze Eval die ganze Zeit in meinen eigenen persönlichen Programmen (und nicht nur in Python). Rückblickend stimme ich absolut zu, dass ich eine Diskussion über die potenziellen Risiken von eval hätte einbeziehen sollen; Das mache ich sowieso immer in meinen Kursen.

Die Quintessenz ist, dass es viele Möglichkeiten gibt, wie dieses Buch verbessert werden kann (es gibt immer). Ich glaube nicht, Eval zu benutzen ist ein fataler Fehler; Es ist angemessen für die Arten von Programmen, die dargestellt werden, und für den Kontext, in dem diese Programme erscheinen. Mir sind keine anderen "Unsicherheiten" in der Art bekannt, wie Python im Buch verwendet wird, aber Sie sollten gewarnt werden (wie das Vorwort erklärt), dass es zahlreiche Stellen gibt, an denen der Code nicht genau "Pythonic" ist.

    
John Zelle 14.04.2013, 19:14
quelle
5

Ja, es ist falsch. Aber ich denke, ich weiß, warum es da drin ist.

Viele Leute benutzen input() in Python 2.x, was eine sehr unglücklicherweise benannte Funktion ist, da sie nicht nur Eingaben liest, sondern auch auswertet. Der Konverter 2to3 konvertiert jede Verwendung von input() in eval(input()) , wie Sie sehen können:

%Vor%

Also meine Vermutung ist, dass es nur ein wenig schlampig ist. Aus der Amazon-Beschreibung:

  

Dies ist die zweite Ausgabe von John Zelles Python-Programmierung, die für Python 3 aktualisiert wurde.

Ich glaube, jemand hat 2to3 auf alle Code-Beispiele angewendet, ohne die Ausgabe gründlich genug zu überprüfen. Also ja, es war ein Fehler, input() in Python 2.x zu verwenden, und es war ein Fehler, 2to3 zu verwenden, ohne die Ausgabe zu überprüfen.

    
Dietrich Epp 14.04.2013 10:28
quelle
4

Da eval in dem von Ihnen gegebenen Beispiel so fehl am Platz und unnötig ist, hätte ich sicherlich Zweifel an der Sicherheit anderer Teile des Buches. Schlägt der Autor vor, dass Sie eine vom Benutzer eingegebene Zeichenfolge an eine SQL-Abfrage anhängen?

Ich denke, es könnte sich lohnen, die E-Mail-Adresse des Autors zu finden und ihn direkt danach zu fragen.

    
Joshua D. Boyd 14.04.2013 04:53
quelle
3

Nun, eval () und input () auf diese Weise zu kombinieren, erzeugt eine rudimentäre, aber möglicherweise sehr schädliche "Shell". Ich habe das Buch nicht gelesen, aber ich nehme es mit einem Körnchen Salz. Es ist nicht nur schlechte Übung, es implementiert eine tödliche Kombination von Funktionen.

    
Chris Richter 14.04.2013 10:18
quelle
2

Ja eval sollte stattdessen% c_de% buchstabiert werden, um die Leute davor zu warnen;) Du solltest es versuchen und es niemals benutzen, außer du musst es unbedingt tun. In diesem Fall ist es intuitiv, stattdessen evil zu verwenden, es ist sogar viel besser lesbar! Auch wenn Sie wirklich müssten, könnten Sie int() verwenden (es werden nur Literale ausgewertet, wie der Name andeutet, so dass der Benutzer keinen schädlichen Code ausführen kann), was eigentlich sicher ist, aber das ist nicht nötig und es gibt Keine Notwendigkeit für ast.literal_eval in diesem Fall.

    
jamylak 14.04.2013 04:41
quelle

Tags und Links