0

私のpythonファイルで、ユーザーからの入力を受け取るGUIウィジェットを作成しました。raw_input() を使用して入力を受け取る Python ファイルに Python モジュールをインポートしました。このモジュールはそのまま使用する必要があり、変更する権利はありません。Python ファイルを実行すると、入力を求められます (インポートされたモジュールの raw_input() による)。その場所で GUI ウィジェットの入力を使用したい。インポートされたモジュールの raw_input() として (ウィジェットから取得した) ユーザー入力を渡すにはどうすればよいですか?

4

1 に答える 1

1

まず、importスクリプトに直接 ing する必要がない場合 (そしてその理由を想像するのが難しい場合)、 または を使用して、モジュール (またはそれにラップされた単純なスクリプト) を別のプロセスとして実行できsubprocessますpexpect

これを具体化してみましょう。このばかげたモジュールを使いたいとしましょうfoo.py:

def bar():
    x = raw_input("Gimme a string")
    y = raw_input("Gimme another")
    return 'Got two strings: {}, {}'.format(x, y)

最初に些細なことを書きますfoo.wrapper.py:

import foo
print(foo.bar())

foo.do_thing()ここで、実際のスクリプトで直接呼び出す代わりにfoo_wrapper、子プロセスとして実行します。

文字列で送信したい入力が既にあると仮定します。これにより、回答の無関係な部分がより単純になります(実際、GUIコードを使用したい場合は、それが可能になります) 、最初に使用している GUI ライブラリを教えていただけない限り、その方法をお見せすることはできません)。

そう:

foo_input = 'String 1\nString 2\n'

with subprocess.Popen([sys.executable, 'foo_wrapper.py'],
                      stdin=subprocess.PIPE, stdout=subprocess.PIPE) as p:
    foo_output, _ = p.communicate(foo_input)

もちろん、実際foo_wrapper.pyには、現在の作業ディレクトリにあると仮定するのではなく、適切なパスを使用する必要がありますが、アイデアを説明するにはこれで十分です。


一方、「私にはそれを変更する権利がありません」が単に「foo プロジェクトの github サイトまたは当社の P4 サーバー上の関連するサブツリーへのチェックイン権を持っていない (そしてすべきではない)」ことを意味する場合、本当に簡単な答え: フォークして、フォークを交換します。

たとえ LGPL のような弱いコピーレフト ライセンスを持っていたとしても、それをフォークし、フォークを変更し、オリジナルと同じライセンスの下でフォークを公開してから、フォークを使用してください。

すべてのターゲットシステムにインストールされている foo パッケージに依存していて、代わりにインストールされている代替 foo に依存できない場合、それはもう少し問題です。しかし、実際に呼び出す関数またはメソッドがraw_inputの実際のコードのほんの一部であるfoo場合は、実行時にモンキーパッチを適用することで修正できfooます。


そして、それは最後の可能性につながります。いつでもraw_inputそれ自体にモンキーパッチを適用できます。

繰り返しになりますが、物事を単純化するために必要な入力は既にあると仮定します。

したがって、最初に置換関数を記述します。

foo_input = ['String 1\n', 'String 2\n']
def fake_raw_input(prompt):
    global foo_input
    return foo_input.pop()

現在、これにパッチを適用するには 2 つの方法があります。通常は、次のようにします。

import foo
foo.raw_input = fake_raw_input

これは、fooその呼び出し内のすべてのコードraw_inputが、通常のビルトインではなく、モジュール グローバルに詰め込んだ関数を参照することを意味します。本当にファンキーなことをしない限り (ビルトインを直接検索してローカル変数などにコピーするなど)、これが答えです。

本当にファンキーなエッジ ケースの 1 つを処理する必要があり、疑わしいことをしてもかまわない場合は、次のようにします。

import __builtin__
__builtin__.raw_input = fake_raw_input

import foo問題の最初のどこかの前にこれを行う必要があります。また、これが意図的に動作することが保証されているのか、誤って動作することが保証されているのか (将来的に修正される必要があるのか​​)、または動作が保証されていないのかは明らかではありません。しかし、それは機能します (少なくとも、おそらく使用している CPython 2.5-2.7 の場合)。

于 2013-07-17T00:38:29.350 に答える