2

を使用して非同期の子プロセスを作成しています。これによりgobject.spawn_async、子プロセスが終了したときに使用する stdout にデータが生成されます。そこで、2 つのコールバックを作成します (最小限の例):

output = ""
def child_read(source, cb_condition):
    for line in source: output += line + "\n"

def child_done(pid, condition, user_data):
    print(user_data)

cpid, cout = gobject.spawn_async(['/bin/ls'],
                      flags = gobject.SPAWN_DO_NOT_REAP_CHILD,
                      standard_output=True)
gobject.child_watch_add(pid=cpid, function=child_done, data=output)
gobject.io_add_watch(os.fdopen(cout, 'r'), gobject.IO_IN | gobject.IO_PRI, child_read)

ここでの明らかな欠陥は、が で再割り当てされるchild_doneため、常に何も出力しないことです。ここでの問題は、構文的に適切で読みやすい (つまり、自己文書化する) 方法でこれを行うにはどうすればよいかということです。確かに、 を読み込むことはできますが、コールバックでどのデータが使用されているかがコールに記録されません。さらに、コールバックは他の目的には使用できません。ここでは C/C++ ポインターのセマンティクスが本当に欠けています。outputchild_readoutputchild_donechild_watch_add

また、ポインターのセマンティクスをエミュレートするワッパー クラスを作成できることも認識していますが、それによって構文が少し肥大化することもあります。それで、これを「pythonic」、つまりエレガントに、素敵で読みやすい方法で行うための提案はありますか?

4

1 に答える 1

0

私は gobject を使用したことがありませんが、Python の質問が SO で未回答のままであるには 4 時間は長いので、試してみます。

文字output列の代わりに文字列のリストを作成します。おそらく、次のようなものです。

output = []

def child_read(source, cb_condition):
    output.extend(source)

def child_done(pid, condition, user_data):
    output_str = '\n'.join(user_data)
    print(output_str)

コードの残りの部分は変更されていません (つまりdata=outputchild_watch_add().

于 2012-09-24T00:39:28.553 に答える