Jupyter Notebook中使用inquirer库出现(25, 'Inappropriate ioctl for device')错误求助
解决Jupyter Notebook中inquirer运行报错(25, 'Inappropriate ioctl for device')的问题
问题描述
使用inquirer编写选择题交互功能,代码为示例代码理论无问题,但在Jupyter Notebook运行时先显示选择界面,随即抛出error: (25, 'Inappropriate ioctl for device')错误,完整报错栈见下文。
运行代码
name = input("What's your name ? ") options = ['Social media', 'Ads', 'TV', 'Other'] questions = [ inquirer.List('options', message = 'Welcome,' + name + '. How did you find out about this app?', choices = options, ), ] answers = inquirer.prompt(questions) print(answers) print(answers['options'])
运行时显示的选择界面
[?] Welcome,David. How did you find out about this app?: Social media > Social media Ads TV Other
完整报错栈
error Traceback (most recent call last) Cell In[25], line 25 17 options = ['Social media', 'Ads', 'TV', 'Other'] 19 questions = [ 20 inquirer.List('options', 21 message = 'Welcome,' + name + '. How did you find out about this app?', 22 choices = options, 23 ), 24 ] ---> 25 answers = inquirer.prompt(questions) 26 print(answers) 27 print(answers['options']) File ~/anaconda3/lib/python3.10/site-packages/inquirer/prompt.py:11, in prompt(questions, render, answers, theme, raise_keyboard_interrupt) 9 try: 10 for question in questions: ---> 11 answers[question.name] = render.render(question, answers) 12 return answers 13 except KeyboardInterrupt: File ~/anaconda3/lib/python3.10/site-packages/inquirer/render/console/__init__.py:38, in ConsoleRender.render(self, question, answers) 35 self.clear_eos() 37 try: ---> 38 return self._event_loop(render) 39 finally: 40 print("") File ~/anaconda3/lib/python3.10/site-packages/inquirer/render/console/__init__.py:51, in ConsoleRender._event_loop(self, render) 48 self._print_header(render) 49 self._print_options(render) ---> 51 self._process_input(render) 52 self._force_initial_column() 53 except errors.EndOfInput as e: File ~/anaconda3/lib/python3.10/site-packages/inquirer/render/console/__init__.py:95, in ConsoleRender._process_input(self, render) 93 def _process_input(self, render): 94 try: ---> 95 ev = self._event_gen.next() 96 if isinstance(ev, events.KeyPressed): 97 render.process_input(ev.value) File ~/anaconda3/lib/python3.10/site-packages/inquirer/events.py:22, in KeyEventGenerator.next(self) 21 def next(self): ---> 22 return KeyPressed(self._key_gen()) File ~/anaconda3/lib/python3.10/site-packages/readchar/_posix_read.py:34, in readkey() 30 def readkey() -> str: 31 """Get a keypress. If an escaped key is pressed, the full sequence is 32 read and returned as noted in `_posix_key.py`.""" ---> 34 c1 = readchar() 36 if c1 in config.INTERRUPT_KEYS: 37 raise KeyboardInterrupt File ~/anaconda3/lib/python3.10/site-packages/readchar/_posix_read.py:18, in readchar() 14 """Reads a single character from the input stream. 15 Blocks until a character is available.""" 17 fd = sys.stdin.fileno() ---> 18 old_settings = termios.tcgetattr(fd) 19 term = termios.tcgetattr(fd) 20 try: error: (25, 'Inappropriate ioctl for device')
问题原因
Jupyter Notebook的输入输出环境并非标准终端(pty),inquirer依赖termios模块修改终端设置以捕获键盘交互,但Notebook的标准输入(stdin)不支持这类终端控制操作,因此触发报错。
解决方案
方案1:改用Jupyter原生交互组件ipywidgets
使用ipywidgets的下拉选择组件替代inquirer,完美适配Notebook环境:
- 先安装ipywidgets(若未安装):
pip install ipywidgets jupyter nbextension enable --py widgetsnbextension
- 替换后的代码:
from ipywidgets import widgets, interact_manual name = input("What's your name ? ") options = ['Social media', 'Ads', 'TV', 'Other'] # 创建下拉选择框 dropdown = widgets.Dropdown( options=options, value=options[0], description=f'Welcome,{name}. How did you find out about this app?:', disabled=False, ) # 处理选择结果 def on_submit(choice): print(f"选择结果: {choice}") # 绑定交互 interact_manual(on_submit, choice=dropdown);
方案2:在标准终端中运行脚本
将代码保存为.py文件(比如survey.py),然后在本地终端(如Linux终端、Windows的Anaconda Prompt)中执行:
python survey.py
此方式下inquirer可正常使用终端交互功能,不会触发报错。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

