python 中 `input()` 获取的值不能直接作为未定义变量传入函数;函数调用前,所有实参必须已存在。正确做法是让函数自身调用 `input()`,并通过 `return` 返回结果,再由调用方接收赋值。
在 Python 编程中,初学者常误以为可以将“尚未定义的变量名”(如 item_bought_1)作为参数传给函数,期
待函数内部为其赋值——这是不可行的。Python 是按值传递(pass-by-object-reference),且函数参数是局部变量,对形参的重新赋值不会影响外部作用域中的同名变量(如果存在);更关键的是,若变量根本未定义,调用时就会立即抛出 NameError。
你遇到的错误:
NameError: name 'item_bought_1' is not defined
正是因为代码在执行 question_asker(item_bought_1, ...) 时,解释器试图查找名为 item_bought_1 的变量,但此时它尚未被创建(input() 还没执行),因此报错。
✅ 正确设计思路:
函数应封装输入逻辑与计算逻辑,不依赖外部变量传入,而是主动获取输入、处理数据,并通过 return 输出结果。调用方负责接收返回值并存储。
以下是优化后的专业写法:
def question_asker():
"""交互式获取单个商品信息,返回 (商品名, 单价, 数量, 小计) 元组"""
item = input("What item has been bought? ").strip()
if not item:
print("Warning: Empty item name. Using 'Unknown'.")
item = "Unknown"
while True:
try:
price = float(input(f"How much is each unit of '{item}'? "))
break
except ValueError:
print("Please enter a valid number for price.")
while True:
try:
qty = int(input(f"How many units of '{item}' have been bought? "))
break
except ValueError:
print("Please enter a valid integer for quantity.")
total = price * qty
return item, price, qty, total
# 调用 4 次,每次接收完整结果
items = []
for i in range(1, 5):
print(f"\n--- Entry #{i} ---")
item, unit_price, quantity, item_total = question_asker()
items.append({
'name': item,
'unit_price': unit_price,
'quantity': quantity,
'total': item_total
})
# 示例:打印简洁表格
print("\n" + "="*50)
print(f"{'Item':<12} {'Price':<8} {'Qty':<6} {'Total':<10}")
print("-"*50)
for it in items:
print(f"{it['name']:<12} ${it['unit_price']:<7.2f} {it['quantity']:<6} ${it['total']:<9.2f}")
print("="*50)? 关键要点总结:
这种设计符合 Python 的清晰性与封装原则:函数职责单一(专注采集+计算),调用方专注流程控制与数据组织。