2012-09-23 5 views
2

gobject.spawn_async으로 비동기 하위 프로세스를 생성합니다.이 프로세스는 자식이 종료 될 때 사용할 표준 출력에 데이터를 생성합니다. 그래서 두 개의 콜백 (최소한의 예)를 만들 : 여기콜백을 사용하여 데이터 전달

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) 

명백한 결함이 outputchild_read에 재 할당되기 때문에 child_done 항상 아무것도 인쇄하지 것입니다. 이제 문제는 문법적으로 훌륭하고 읽기 쉬운 (즉 자체 문서화) 방식으로 어떻게해야합니까? 물론 outputchild_done으로 읽을 수는 있지만 child_watch_add 호출은 어떤 데이터가 콜백에 사용되었는지 문서화하지 않습니다. 플러스 콜백은 다른 용도로 사용할 수 없습니다. C/C++ 포인터 의미론이 실제로 없어졌습니다. 원하는대로 할 수 있습니다.

나는 또한 포인터 의미를 에뮬레이션하는 wapper 클래스를 만들 수 있다는 것도 알고 있지만, 그 역시 비슷한 구문을 사용합니다. 그럼,이 "pythonic", 즉 을 우아하게으로 작성하는 제안은 훌륭하고 읽기 쉬운 방식으로 진행됩니까?

답변

0

필자는 gobject를 사용하지 않았지만, Python 질문에 대해서는 아직 답변하지 않은 채 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) 

코드의 나머지 부분은 변경되지 않습니다 (즉, 여전히 child_watch_add()에 호출 전에 들어 본

+0

그래를 data=output을 사용하지만, 출력에 사용되기 때문에에만 맞습니다. 데이터를 수집합니다. 출력이 단일 int 인 경우 목록에 배치하는 것도 부 풀릴 수 있습니다. –

+0

예, 여기서 사용하는 패턴을 구현하려면 'output'이 변경 가능해야하며 Python에서는 정수와 문자열이 불투명합니다. (이 점을 이해하는 것은 꽤 분명합니다.이 주석은 주로 나중에 읽는 다른 모든 사람들을위한 것입니다.) –

관련 문제