3

既存のコード スニペットでは、

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()

可能であれば残りのコードを変更せずに、IPython が使用可能な場合、IPython の対話型シェルを使用するようにこれを変更するにはどうすればよいですか。

2行目をスワップアウトしようfrom code import InteractiveConsoleとしましfrom IPython.core import interactiveshell as InteractiveConsoleたが、明らかに、直接交換可能なクラスではありません。

これを (コード ベースの残りの部分への変更を最小限に抑えて) 実行する最善の方法はIPythoncodeですかIPython?

4

2 に答える 2

1

ここに私自身の試みがあります:-

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()

これはうまくいくようですが、おそらくカスタムメソッド/機能cacheを失いました。stdout

批判、編集、改善提案は大歓迎です!

于 2012-04-24T15:32:05.613 に答える
0

私は大した専門家ではありません(間違っている場合は反対票を投じないでください)が、次のようなもので行くことができると思います

試してください: IPython.core から InteractiveShell を InteractiveConsole #facade コードとしてここにインポートします。

このようにして、存在するcode.InteractiveConsole場合はを取得し、IPython.core.interactiveshellそれ以外の場合は として再マップしInteractiveConsoleます。とにかくメソッド名とシグネチャを変更するか、ある種のファサードまたはアダプターを構築してみる必要があります。

考えられる 1 つの方法は、必要なすべての関数呼び出しを名前空間にエイリアスし、このエイリアスを使用することです。「ファサード」コードよりも、同じシグネチャ (名前とパラメーター リスト) で関数を定義し、それらに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)
于 2012-04-24T15:25:20.210 に答える