如何检测Python函数是否请求输入并动态提供输入?
动态响应Python函数的输入请求
问题背景
有一个不可修改的Python函数:
import random def randomfunc(): x = random.randint(0,10) # some code here which generates a name/text randomly and stores it in a .txt file locally/cloud if x%2 == 0: y=input("Enter your name:") # 需要输入随机生成的那个名称/文本 print("Your name is ",y) else: print("You got an odd number")
需求是:运行该函数时,自动检测是否请求输入,若需要则动态提供随执行过程变化的输入值,否则不做操作。
尝试过的方案及问题
曾使用unittest.mock.patch预设输入值,但输入是固定的,无法动态生成:
import builtins from unittest.mock import patch with patch('builtins.input') as input_mock: input_mock.side_effect = [ 'My Name', ] print(input('Enter your name:'))
此外,尝试wexpect模块时出现错误:OSError: [WinError 6] The handle is invalid。
解决方案
方案1:利用mock的动态side_effect函数
给input_mock.side_effect赋值一个函数,而非固定列表,该函数可在每次调用input()时动态生成所需输入值。比如读取本地生成的txt文件内容作为输入:
import builtins from unittest.mock import patch import random # 模拟原函数中生成随机名称并写入文件的逻辑 def generate_random_name(): names = ["Alice", "Bob", "Charlie", "Diana"] name = random.choice(names) with open("generated_name.txt", "w") as f: f.write(name) return name def dynamic_input(prompt): # 根据输入提示判断是否需要响应 if prompt == "Enter your name:": # 读取当前生成的名称 with open("generated_name.txt", "r") as f: return f.read().strip() # 其他输入请求可按需扩展处理 return "" # 执行目标函数并动态响应输入 with patch('builtins.input', side_effect=dynamic_input): randomfunc()
此方案中,dynamic_input会在每次input()被调用时触发,可根据执行过程中的实时数据(比如本地文件、接口返回值)生成输入。
方案2:修复Windows下wexpect的错误
Windows下出现WinError 6多因终端模式设置问题,可尝试以下调整:
import wexpect # 启动子进程时指定编码和poll模式 child = wexpect.spawn('python your_script.py', encoding='utf-8', use_poll=True) # 等待输入提示出现 child.expect("Enter your name:") # 动态获取输入值(示例为读取本地文件) with open("generated_name.txt", "r") as f: input_val = f.read().strip() child.sendline(input_val) # 输出执行结果 print(child.read()) child.close()
若仍报错,尝试以管理员身份运行脚本,或检查是否有其他程序占用终端句柄。
方案3:使用subprocess配合管道(独立脚本场景)
如果原函数作为独立脚本运行,可用subprocess创建子进程,通过管道动态发送输入:
import subprocess import random # 先执行生成随机名称的逻辑 def generate_random_name(): names = ["Alice", "Bob", "Charlie", "Diana"] name = random.choice(names) with open("generated_name.txt", "w") as f: f.write(name) return name generate_random_name() # 启动子进程检测是否需要输入 proc = subprocess.Popen(['python', 'your_script.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) output, _ = proc.communicate(timeout=5) if "Enter your name:" in output: # 读取动态生成的输入值并发送给子进程 with open("generated_name.txt", "r") as f: input_val = f.read().strip() proc = subprocess.Popen(['python', 'your_script.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) stdout, stderr = proc.communicate(input=input_val + '\n') print(stdout) else: print(output)
此方案适合对执行流程有预判的场景,需先判断是否会触发输入请求。
内容的提问来源于stack exchange,提问作者Hello World
相关产品推荐
相关产品推荐

