2011-10-10 18 views
29

Attualmente insegno python agli studenti universitari del primo anno e sono stato sorpreso di apprendere che la funzione apparentemente innocua input, che alcuni dei miei studenti avevano deciso di utilizzare (e che erano confusi dal comportamento strano), nascondeva una chiamata allo eval dietro esso.È sempre utile usare l'input di Python su raw_input?

Quindi la mia domanda è, perché il input funzione di chiamata eval, e che cosa sarebbe questo mai essere utile per che non sarebbe stato più sicuro a che fare con raw_input? Capisco che questo è stato cambiato in Python 3, ma sembra una decisione di design inusuale in primo luogo.

Python 2.x input function documentation

+7

È utile per il codice-golf –

+0

Per rispondere al "perché", il primo REPL di Python potrebbe essere stato "while 1: print input()'. Scommetto che in quel periodo antico, il supporto alle buone pratiche di programmazione non era così alto nella lista delle priorità di Python come lo è ora. Python 3's 'while True: print (eval (input()))' potrebbe anche sembrare più confuso - tutte quelle parentesi annidate! –

risposta

34

E 'sempre utile per utilizzare il metodo di Python 2 è finita raw_input?

No.


input() valuta il codice utente dà. Mette la piena potenza di Python nelle mani dell'utente. Con le espressioni generatore/list comprehensions, __import__ e gli operatori if/else, letteralmente tutto ciò che Python può fare può essere ottenuto con una singola espressione. Gli utenti malintenzionati possono utilizzare input() per rimuovere i file (__import__('os').remove('precious_file')), monkeypatch il resto del programma (setattr(__import__('__main__'), 'function', lambda:42)), ... qualsiasi cosa.

Un utente normale non dovrà utilizzare tutte le funzionalità avanzate. Se non hai bisogno di espressioni, usa ast.literal_eval(raw_input()) - la funzione literal_eval è sicura.

Se stai scrivendo per utenti esperti, dai loro un modo migliore di inserire il codice. Plugin, moduli utente, ecc. - Qualcosa con la sintassi Python completa, non solo la funzionalità.

Se sei assolutamente sicuro di sapere cosa stai facendo, diciamo eval(raw_input()). Lo eval urla "Sono pericoloso!" all'occhio allenato. Ma le probabilità non ti serviranno mai.


input() stato uno dei vecchi errori di progettazione che Python 3 è solving.

+0

Questo è quello che stavo pensando, anche se volevi la funzionalità di 'input', se tu avessi' eval (raw_input()) 'allora avresti almeno capito che era pericoloso. E non c'è davvero una buona ragione per usarlo altrimenti. Grazie! – luketparkinson

4

input è praticamente utile solo come un blocco di costruzione per una shell pitone interattiva. Hai certamente ragione che è sorprendente funziona come fa ed è piuttosto troppo specifico per essere incorporato - che presumo sia il motivo per cui è stato rimosso da Python 3.

7

La funzione di input di Python restituisce un oggetto che è il risultato di valutazione dell'espressione. funzione raw_input restituisce una stringa

name = "Arthur" 
age = 45 

first = raw_input("Please enter your age ") 
second = input("Please enter your age again ") 

# first will always contain a string 

# second could contain any object and you can even 
# type in a calculation and use "name" and "age" as 
# you enter it at run time ... 

print "You said you are",first 
print "Then you said you are",second 

esempi di esecuzione che:

Esempio: 1

Prompt$ python yraw 
Please enter your age 45 
Please enter your age again 45 
You said you are 45 Then you said you are 45 

Esempio: 2

Prompt$ python yraw 
Please enter your age 45 + 7 
Please enter your age again 45 + 7 
You said you are 45 + 7 Then you said you are 52 
Prompt$ 

D. Perché l'ingresso funzione chiamata eval?

A. Si consideri lo scenario in cui utente immette un'espressione '45 + 7' in ingresso, ingresso darà risultato corretto rispetto a raw_input in Python 2.x

+1

in alternativa è possibile immettere 'quit()' che è piuttosto pericoloso se si fa parte di una sezione critica del codice ... – tobyodavies

+8

Oppure è possibile immettere '__import __ ('os'). Remove ('precious_file')' che è piuttosto pericoloso * ovunque *. ['ast.literal_eval (raw_input())'] (http://docs.python.org/library/ast.html#ast.literal_eval) è una scelta molto migliore in praticamente tutte le situazioni. Non c'è da meravigliarsi se [l'input di Python 3()] (http://docs.python.org/py3k/library/functions.html#input) funziona come il raw_input() di 2. –

+7

Non sono d'accordo con questa risposta. Perché consideri il "risultato corretto" perché l'input sia 52? Prenderò in considerazione il risultato corretto "inserisci un numero". Non c'è una buona ragione per un programma che richiede un numero per calcolare il risultato di un'espressione Python che l'utente può dare. Non solo questo comportamento assurdo, ma anche un serio rischio per la sicurezza, come ha sottolineato Petr. La domanda era "è utile" e la risposta è "no". – mgiuca

1

raw_input è migliore, restituisce sempre l'input dell'utente senza modifiche. Viceversa la funzione input() proverà a convertire le cose immesse come se fossero codice Python e ha problemi di sicurezza, quindi dovresti evitarlo.

Nel programma reale non utilizzare input(), Analizzare l'input con qualcosa che gestisce lo specifico formato di input che ci si aspetta, non valutando l'input come codice Python.