python c cmd_在Python cmd模块中处理CTRL-C
我發現了一些使用Ctrl-C實現所需行為的hacky方法.
設置use_rawinput = False并替換stdin
這個(或多或少……)粘在cmd.Cmd的公共接口上.不幸的是,它禁用了readline支持.
您可以將use_rawinput設置為false并傳遞一個不同的類文件對象來替換Cmd .__ init __()中的stdin.實際上,只在此對象上調用readline().因此,您可以為stdin創建一個包裝器,捕獲KeyboardInterrupt并執行您想要的行為:
class _Wrapper:
def __init__(self,fd):
self.fd = fd
def readline(self,*args):
try:
return self.fd.readline(*args)
except KeyboardInterrupt:
print()
return '\n'
class TestShell(cmd.Cmd):
def __init__(self):
super().__init__(stdin=_Wrapper(sys.stdin))
self.use_rawinput = False
self.prompt = '$'
def precmd(self,line):
if line == 'EOF':
return 'exit'
return line
def emptyline(self):
pass
def do_exit(self,line):
return True
TestShell().cmdloop()
當我在終端上運行它時,Ctrl-C顯示^ C并切換到新行.
猴子補丁輸入()
如果你想要input()的結果,除了你想要Ctrl-C的不同行為,一種方法是使用不同的函數而不是input():
def my_input(*args): # input() takes either no args or one non-keyword arg
try:
return input(*args)
except KeyboardInterrupt:
print('^C') # on my system,input() doesn't show the ^C
return '\n'
但是,如果您只是盲目地設置input = my_input,則會得到無限遞歸,因為my_input()將調用input(),現在它本身就是.但這是可以修復的,你可以在cmd模塊中修補__builtins__字典,以便在Cmd.cmdloop()期間使用修改后的input()方法:
def input_swallowing_interrupt(_input):
def _input_swallowing_interrupt(*args):
try:
return _input(*args)
except KeyboardInterrupt:
print('^C')
return '\n'
return _input_swallowing_interrupt
class TestShell(cmd.Cmd):
def cmdloop(self,*args,**kwargs):
old_input_fn = cmd.__builtins__['input']
cmd.__builtins__['input'] = input_swallowing_interrupt(old_input_fn)
try:
super().cmdloop(*args,**kwargs)
finally:
cmd.__builtins__['input'] = old_input_fn
# ...
請注意,這會更改所有Cmd對象的input(),而不僅僅是TestShell對象.如果這是你不能接受的,你可以……
復制Cmd.cmdloop()源并進行修改
由于你是子類化它,你可以讓cmdloop()做你想做的任何事情. “你想要的任何東西”可能包括復制Cmd.cmdloop()的部分并重寫其他部分.通過調用另一個函數替換對input()的調用,或者在重寫的cmdloop()中捕獲并處理KeyboardInterrupt.
如果您害怕使用新版本的Python更改底層實現,您可以將整個cmd模塊復制到一個新模塊中,并更改您想要的內容.
總結
以上是生活随笔為你收集整理的python c cmd_在Python cmd模块中处理CTRL-C的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [资源]181个Python开源项目分享
- 下一篇: python知识图谱可视化_知识图谱可视