1

Gael Varoquauxによる traitsui チュートリアルについて質問があります。コード スニペット 7 では、カメラから画像を取得するためのスレッドを生成するための CaptureThread クラスを作成しています。彼は Camera クラスも作成しています。

class TextDisplay(HasTraits):
    string = String()
    view = View(Item('string', show_label=False, springy=True, style='custom'))

class CaptureThread(Thread):
    def run(self):
        #self.display is set outside the class definition by the caller
        self.display.string = 'Camera started\n' + self.display.string
        n_img = 0
        while not self.wants_abort:
            sleep(0.5)
            n_img += 1
            self.display.string = ' %d image captured\n' % n_img \
                                        + self.display.string
        self.display.string = 'Camera stopped\n' + self.display.string

class Camera(HasTraits):
    start_stop_capture = Button()
    display = Instance(TextDisplay)
    capture_thread = Instance(CaptureThread)

    view = View( Item('start_stop_capture', show_label=False))

    def _start_stop_capture_fired(self):
        if self.capture_thread and self.capture_thread.isAlive():
            self.capture_thread.wants_abort = True
        else:
            self.capture_thread = CaptureThread()
            self.capture_thread.wants_abort = False
            self.capture_thread.display = self.display
            self.capture_thread.start()

このコードについて 2 つの質問があります。

1) Camera クラス定義で、Instance(CaptureThread) を呼び出して、capture_thread を Trait にするのはなぜですか? CaptureThread は単なるスレッド クラスです。なぜそれから特性インスタンスを作成する必要があるのでしょうか?

2) CaptureThread クラスで、フィールド self.display.string と self.wants_abort を使用します。これら 2 つのフィールドは、コンストラクター メソッドを介して渡されるのではなく、Camera クラスによってクラス定義の外で割り当てられます。これはベストプラクティスですか?CaptureThread のユーザーがこれら 2 つのフィールドの設定を忘れると、エラーが発生するためです。そのようなものをいつ割り当てることができるかを知るための賢明なガイドラインはありますか、それともコンストラクターを使用してそれらを割り当てる必要がありますか?

これらの質問が理にかなっており、これが彼らに尋ねるのに適切な場所であることを願っています! ありがとう、ラボジャンキー

4

1 に答える 1

2
  1. capture_thread = Instance(CaptureThread)のインスタンスを作成しませんCaptureThreadCameraクラスが作成されるときにクラスによって消費されるのは、より多くの宣言です。orのインスタンスである必要があり、デフォルトで になるCameraという名前の属性を持つことをそのクラスに伝えます。このデフォルトにより、「初期化されている場合はテストし、そうでない場合は作成する」ロジックが、少なくとも一部の人々の好みに合わせて少しきれいになります。capture_threadCaptureThreadNoneNoneself.capture_thread_start_stop_capture_fired()

  2. サブクラスの場合threading.Thread、そうです。唯一の方法ではありませんが、これは慣用的な方法の 1 つです。Threadにはすでに特定の__init__実装があり、それをオーバーライドして別のことを行うことができますが、この場合、作成者がそうすることを避けるのは理解できます。

    これは、実際にキーワード引数を使用するサブクラスを初期化する慣用的な方法ではありません。HasTraits

于 2013-09-11T10:36:18.430 に答える