[英]Using IPython interchangeably with code module if IPython exists
In an existing code snippet, I have 在现有的代码段中,我有
import sys
from code import InteractiveConsole
class FileCacher:
"Cache the stdout text so we can analyze it before returning it"
def __init__(self):
self.reset()
def reset(self):
self.out = []
def write(self, line):
self.out.append(line)
def flush(self):
output = '\n'.join(self.out)
self.reset()
return output
class Shell(InteractiveConsole):
"Wrapper around Python that can filter input/output to the shell"
def __init__(self):
self.stdout = sys.stdout
self.cache = FileCacher()
InteractiveConsole.__init__(self)
return
def get_output(self):
sys.stdout = self.cache
def return_output(self):
sys.stdout = self.stdout
def push(self, line):
self.get_output()
# you can filter input here by doing something like
# line = filter(line)
InteractiveConsole.push(self, line)
self.return_output()
output = self.cache.flush()
# you can filter the output here by doing something like
# output = filter(output)
print output # or do something else with it
return
if __name__ == '__main__':
sh = Shell()
sh.interact()
How do I modify this to use IPython's interactive shell if IPython is available without changing the rest of the code if possible. 如果IPython可用,如何在不更改其余代码的情况下修改它以使用IPython的交互式外壳。
I attempted swapping out line 2 from code import InteractiveConsole
with from IPython.core import interactiveshell as InteractiveConsole
but obviously, it's not a directly interchangeable class. 我尝试将
from code import InteractiveConsole
第2行与from IPython.core import interactiveshell as InteractiveConsole
换出from IPython.core import interactiveshell as InteractiveConsole
但是显然,它不是直接可互换的类。
What's the best way to do this (with minimal change to the rest of the code base) with a try except and using IPython
in preference over code
module when IPython
exists? 尝试进行此操作的最佳方法(对代码库的其余部分进行最少的更改)尝试除
IPython
存在之外,并优先于code
模块使用IPython
进行此操作吗?
Here's my own attempt:- 这是我自己的尝试:
import sys
from code import InteractiveConsole
class FileCacher:
"Cache the stdout text so we can analyze it before returning it"
def __init__(self):
self.reset()
def reset(self):
self.out = []
def write(self, line):
self.out.append(line)
def flush(self):
output = '\n'.join(self.out)
self.reset()
return output
class Shell(InteractiveConsole):
"Wrapper around Python that can filter input/output to the shell"
def __init__(self):
self.stdout = sys.stdout
self.cache = FileCacher()
InteractiveConsole.__init__(self)
return
def get_output(self):
sys.stdout = self.cache
def return_output(self):
sys.stdout = self.stdout
def push(self, line):
self.get_output()
# you can filter input here by doing something like
# line = filter(line)
InteractiveConsole.push(self, line)
self.return_output()
output = self.cache.flush()
# you can filter the output here by doing something like
# output = filter(output)
print output # or do something else with it
return
if __name__ == '__main__':
try:
import IPython
IPython.embed()
except:
sh = Shell()
sh.interact()
which seems to work fine but I probably lost the cache
and stdout
custom methods/functionalities. 这似乎工作正常,但我可能会丢失
cache
和stdout
自定义方法/功能。
Any criticism, edits and improvement suggestions welcome! 欢迎任何批评,编辑和改进建议!
I'm not a big expert (so plese don't downvote if I'm wrong), but I think you can go with something like 我不是专家,所以如果我错了,请不要投票,但是我认为您可以选择
try: from IPython.core import interactiveshell as InteractiveConsole #facade code here, if needed except ImportError: from code import InteractiveConsole #fallback case 尝试:从IPython.core从此处将Interactiveshell作为InteractiveConsole #facade代码导入,如果需要的话,除了ImportError:从代码中导入InteractiveConsole #fallback案例
This way you'll get your code.InteractiveConsole
if it's present and IPython.core.interactiveshell
otherwise remapped as InteractiveConsole
. 这样,您将获得
code.InteractiveConsole
如果存在),而IPython.core.interactiveshell
否则将重新映射为InteractiveConsole
。 You'll have to change method names and signatures anyway, or try build some kind of facade or adapter. 无论如何,您都必须更改方法名称和签名,或者尝试构建某种外观或适配器。
One possible way is to alias all required function calls into your namespace and use this aliases. 一种可能的方法是将所有必需的函数调用别名到您的名称空间中,并使用此别名。 Than in 'facade' code you'll just have to define functions with same signatures (names and parameter lists) and make them call
interactiveshell
functions: 比在“外观”代码中,您只需要定义具有相同签名(名称和参数列表)的函数,并使它们称为
interactiveshell
函数:
try:
from IPython.core import interactiveshell as InteractiveConsole
def func1(a,b,c):
InteractiveConsole.some_other_func(a,b,c)
except ImportError:
from code import InteractiveConsole #fallback case
func1 = InteractiveConsole.func1
...
func1(a,b,c)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.