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