Python函数如何处理输入中的未定义项,自动转为字符串加入结果列表
问题根因
你之前的推测完全正确:Python的参数求值规则决定了,调用函数时,解释器会先完整解析完传入的所有参数,再执行函数内部的代码。
像你写的Roll([ListA, ListB, Thanks])这行代码,执行时会依次解析列表中的每个标识符:
- 遇到已定义的
ListA、ListB,正常拿到对应的列表值 - 遇到未定义的
Thanks,直接抛出NameError: name 'Thanks' is not defined
这个报错发生在参数解析阶段,代码根本还没进入Roll的函数体,自然你在函数内部加的try-except捕获逻辑完全触发不了。
最小改动的实现方案
严格来说完全不改原有调用的裸写法是做不到的——只要在调用行直接写未定义变量,解释器在解析该行代码时就会直接终止运行,没有任何办法把值传到函数内部。
只需要在原有写法的基础上做极小幅调整,就能实现你要求的效果:把传入Roll的列表整体用引号包裹,让函数在自己的执行域内解析表达式,自动捕获未定义的标识符。
调整后的完整代码:
import random import re ListA = ["Hi", "Hello"] ListB = ["Bye", "Goodbye", "Farewell"] ListC = [] def Roll(align_expr): global_vars = globals() ListC.clear() # 避免多次调用时列表重复累加 # 拆分表达式内的单个元素 raw_items = [item.strip() for item in re.findall(r'[^,\[\]]+', align_expr) if item.strip()] for item in raw_items: try: # 尝试解析元素的实际定义值 parsed_val = eval(item, {"__builtins__": None}, global_vars) except NameError: # 未定义的元素直接转为同名字符串 ListC.append(item) continue # 原有核心逻辑:是列表就随机抽一个,非列表直接加入 if isinstance(parsed_val, list): ListC.append(random.choice(parsed_val)) else: ListC.append(parsed_val) print(ListC)
对应的调用方式,仅在原有写法外多加一对引号,几乎不改变原有书写习惯:
# 原有会报错的裸写法:Roll([ListA, ListB, Thanks]) # 调整后的调用: Roll("[ListA, ListB, Thanks]")
运行后输出完全匹配你预期的结果:
['Hello', 'Farewell', 'Thanks']
逻辑说明
- 完全保留了你已经调试通过的核心随机抽选逻辑,没有做破坏性修改
- 自动识别元素类型:列表项正常执行随机抽取,普通非列表值直接加入结果,遇到未定义的标识符自动转为同名字符串,不会触发运行报错
- 解决了原函数多次调用时
ListC重复累加的小问题,每次调用都会重置结果列表
内容的提问来源于stack exchange,提问作者A Mild Migraine
相关产品推荐
相关产品推荐

