2011-10-10 27 views
29

我現在教大學一年級學生的蟒蛇,我很驚訝地得知,看似無害input功能,我的一些同學已經決定使用(和奇的行爲感到困惑),躲在調用eval背後它。使用Python輸入超過raw_input有用嗎?

所以我的問題是,爲什麼input函數調用eval,這會有什麼用處,因爲它與raw_input不會更安全?我明白這已經在Python 3中發生了變化,但它首先看起來像是一個不尋常的設計決定。

Python 2.x input function documentation

+7

這對於代碼高爾夫 –

+0

有用回答「爲什麼」 - Python的第一個REPL可能是'while 1:print input()'。我敢打賭,在那個古老的時代,支持好的編程實踐在Python的優先級列表上並不像現在這樣高。 Python 3的'while True:print(eval(input()))'甚至可能更容易混淆 - 所有嵌套的括號! –

回答

34

是它曾經有用到超過使用Python 2的輸入的raw_input?


input()評估用戶給它的代碼。它將Python的全部功能交付給用戶。通過使用生成器表達式/列表解析,__import__if/else運算符,Python可以做的任何事情都可以通過單個表達式來實現。惡意用戶可以使用input()刪除文件(__import__('os').remove('precious_file')),monkeypatch程序的其餘部分(setattr(__import__('__main__'), 'function', lambda:42))......任何東西。

一般用戶不需要使用所有的高級功能。如果您不需要表情,請使用ast.literal_eval(raw_input()) - literal_eval功能是安全的。

如果你正在編寫針對高級用戶,給他們輸入代碼更好的方法。插件,用戶模塊等等 - 有了完整的Python語法,而不僅僅是功能。

如果你絕對相信你知道自己在做什麼,說eval(raw_input())eval尖叫聲「我很危險!」到訓練有素的眼睛。但是,你不會需要這個。


input()是Python 3正在解決的舊設計錯誤之一。

+0

這就是我在想的,即使你想'輸入'的功能,如果你做了'eval(raw_input())',那麼你至少會看到它是危險的。否則,沒有什麼好的理由使用它。謝謝! – luketparkinson

4

input幾乎是只能作爲基石的交互式Python外殼有用。你肯定是正確的,這是令人驚訝它的工作方式是這樣,而且未免目的,具體是一個內置的 - 我猜,這位就是爲什麼它被認爲是從Python中取出3

7

Python中輸入函數返回一個對象,是評估表達式的結果 。 的raw_input函數返回字符串運行

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 

例子:

實施例: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 

實施例: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$ 

Q.爲什麼輸入函數調用eval?

A.考慮這樣用戶在輸入輸入公式'45 + 7' 的情況下,比在Python 2.x到輸入的raw_input將給出正確的結果

+1

或者他們可以輸入'quit()'這是相當危險的,如果你是通過代碼的關鍵部分的一部分... – tobyodavies

+8

或者他們可以輸入'__import __('os')。remove('precious_file')'這是相當危險*任何地方*。 ['ast.literal_eval(raw_input())'](http://docs.python.org/library/ast.html#ast.literal_eval)在幾乎所有情況下都是更好的選擇。難怪[Python 3的input()](http://docs.python.org/py3k/library/functions.html#input)像2的raw_input()一樣工作。 –

+7

我不同意這個答案。爲什麼你認爲輸入的「正確結果」是52?我認爲正確的結果是「請輸入一個數字」。對於要求計算用戶可能給出的Python表達式的結果的程序,沒有什麼好理由。正如Petr指出的那樣,這種荒謬的行爲不僅是一種嚴重的安全風險,也是一種嚴重的安全風險問題是「輸入有用」,答案是「否」。 – mgiuca

1

raw_input更好,它總是返回用戶的輸入而沒有改變。 反過來input()函數會嘗試轉換你輸入的東西,就像它們是Python代碼一樣,它有安全問題,所以你應該避免它。

在實際的程序中,不要使用input(),而是通過處理特定輸入格式的東西解析輸入,而不是通過將輸入評估爲Python代碼。