Python 3 中 input() 是 Python 2 raw_input() 的重命名与语义收束,移除了危险的 eval 式 input();兼容写法为 try: input = raw_input except NameError: pass;int(input()) 需先 strip() 并捕获 ValueError。

Python 2 的 raw_input 在 Python 3 中就是 input,不是“变成”,而是“重命名+语义收束”——它删掉了危险的 input,只保留安全的字符串读取行为。
Python 2 的 input() 为什么被干掉?
因为它是 eval(raw_input()),不加任何防护就执行用户输入的任意代码。比如输 __import__('os').system('rm -rf /'),真会删文件。这不是教学演示,是真实线上漏洞源头。Python 3 不容忍这种隐式求值,所以直接移除了这个接口。
常见错误现象:NameError: name 'abc' is not defined 或 SyntaxError —— 用户输了个没引号的字符串,Python 2 的 input() 就去当变量名查了。
- Python 2:
input("x: ")输入42→ 得int;输入hello→ 报NameError - Python 3:
input("x: ")输入42→ 得str;输入hello→ 得"hello"(原样)
如何让一段代码同时跑在 Python 2 和 Python 3 上?
核心思路:在 Python 2 下把 raw_input 赋给 input 名,覆盖掉危险的原生 input;Python 3 无需动作。
立即学习“Python免费学习笔记(深入)”;
最简兼容写法(无依赖):
try:
input = raw_input
except NameError:
pass
之后所有 input(...) 都返回字符串,行为一致。
- 别用
from __future__ import print_function这类导入来解决输入问题——它不管用 - 如果项目已用
six,直接上six.input(),它内部就是上面那段逻辑 - 避免在兼容层里用
eval(input())回退旧行为——这等于主动打开攻击面
为什么 int(input(...)) 会报 ValueError?
因为 input() 返回的是纯字符串,而 int() 对空格、换行、Unicode BOM、中文数字都完全不认。用户按个回车或粘贴带空格的数字,int() 就崩。
健壮写法示例:
while True:
s = input("Enter number: ").strip()
if not s:
continue
try:
x = int(s)
break
except ValueError:
print("Not a valid integer")
-
strip()必须加,否则用户输" 42 "或带尾随换行的粘贴内容会失败 - 别依赖
sys.stdin.readline().rstrip('\n\r')除非你明确需要保留开头/中间空格——普通场景input().strip()更直白 - 若需解析 JSON 片段、列表字面量等复杂结构,用
ast.literal_eval(),不是eval()
真正容易被忽略的点:输入内容可能含不可见控制字符(比如从网页复制的带零宽空格的数字),strip() 清不掉。这时候得上 s.encode('utf-8').decode('utf-8', 'ignore') 或正则清洗,但绝大多数 CLI 工具根本不需要走到这一步——先确保 strip() 和 try/except 写对,已经挡住 95% 的现场翻车。


















