2017-11-21 12 views
1

)は、以下の試験コードで

class1.stop_callback(ねじクラスを介して変数を渡す従ってclass3.stopあるべき=真

をclass2.stop従ってclass1.stop =真

を設定します本当ですが、そうではありません。

class1.stop_callback()はプログラムを停止する必要がありますが、それは行いません。 私は何が間違っていますか?

あなたはPythonでrepl.it https://repl.it/@bahtsiz_bedevi/classtest

import threading 
import time 


class Class1(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.stop = False 

    def stop_callback(self): 
     self.stop = True 

    def run(self): 
     class2 = Class2() 
     class2.stop = self.stop 
     class2.start() 
     while True: 
      time.sleep(1) 
      print("{} stop status: {}".format(self.__class__, "True" if self.stop else "False")) 
      if self.stop: 
       break 


class Class2(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.stop = False 

    def run(self): 
     class3 = Class3() 
     class3.stop = self.stop 
     while True: 
      time.sleep(1) 
      print("{} stop status: {}".format(self.__class__, "True" if self.stop else "False")) 
      if self.stop: 
       break 
      class3.foo() 


class Class3: 
    def __init__(self): 
     self.stop = False 

    def foo(self): 
     while True: 
      time.sleep(1) 
      print("{} stop status: {}".format(self.__class__, "True" if self.stop else "False")) 
      if self.stop: 
       break 


class1 = Class1() 
class1.start() 
for i in range(10): 
    time.sleep(1) 
class1.stop_callback() 
+1

あなたはすでに 'class1.stop'の値を' class2.stop'にコピーした後に 'class1.stop'を' True'に設定してください。私はここで何か見落としていますか?あるいは 'class2.stop'を' class1.stop'への参照の一種として使用したいのですか? –

+0

希望する出力は何ですか、プログラムで何をしたいですか? – PrestonM

+0

@PrestonM "したがってclass3.stopはTrueであるべきですが、そうではありません。それは問題ですが、出力は重要ではありません。 –

答えて

1

上でコードをテストすることができ、変数はオブジェクトの名前です。 Falseclass1.stopに、class1.stopclass2.stopに割り当てると、Falseclass2.stopが割り当てられます。

代わりにclass1.stopへの参照が必要ですが、これはPythonでの割り当ての仕方ではありません。これを回避する1つの方法は、リストを使用することです。あなたは同じリストを保持し、唯一の最初のインデックスの値を変更する場合は、あなたが望むものを達成することができます:

stop1 = [False] 
stop2 = stop1 
assert stop2[0] == False 
stop1[0] = True 
assert stop2[0] == True 
+0

Class2の中に "class3.stop = self.stop"という行があるので、class1.stopをclass2.stopにclass3.stopに割り当てます。 –

+0

最初の文章をもう一度お読みください。 'class1.stop'を' class2.stop'に代入することによって、現在の値、 'False'を' class2.stop'に代入します。 –

+0

今私は参照してください:)ありがとう! –

1

Class3は(メインスレッドで実行されていないにも関わらず)Thread様クラスではありませんので、あなたはが返されるまでclass3.stopの値を変更することはできません。 は、class3.stopの値が変更されるまで戻らないため、プロセスを停止する方法はなく、永久に実行されます。

Class3Threadに設定することをお勧めします。実行中にメソッドを呼び出すことができます。これがあまりにもオーバーヘッドである場合、またはclass2のインスタンスごとに複数回実行する場合は、fooを定義してからClass2.runメソッド内で実行することができます。


編集:私はフロリアンのポイントを言及するつもりだったが、以来、 - 彼の提案された解決策のように - 変更可能なオブジェクトが割り当て中に渡ってキャリーを行い、私はあなたがすでにを通じてこの部分を考えていたかどうかわかりませんでした。

以下は改訂コードです。これらの奇妙なプリントと同じラインで起こった文

  • while not self.stopの使用ではなく、break sのif
  • Class3
  • でのスレッドの使用を防止するための threading.Lockの使用

    • の点に注意してください。
      import threading 
      import time 
      
      printLock = threading.Lock() 
      p = print 
      
      def print(*a, **b): 
          with printLock: 
           p(*a, **b) 
      
      
      class Class1(threading.Thread): 
          def __init__(self): 
           threading.Thread.__init__(self) 
           self.stop = False 
      
          def stopMe(self): 
           self.stop = True 
      
          def run(self): 
           class2 = Class2() 
           class2.start() 
           while not self.stop: 
            time.sleep(1) 
            print("{} stop status:{:6}".format(self.__class__, str(self.stop))) 
           class2.stopMe() 
      
      
      class Class2(threading.Thread): 
          def __init__(self): 
           threading.Thread.__init__(self) 
           self.stop = False 
      
          def stopMe(self): 
           self.stop = True 
      
          def run(self): 
           class3 = Class3() 
           class3.start() 
           while not self.stop: 
            time.sleep(1) 
            print("{} stop status:{:6}".format(self.__class__, str(self.stop))) 
           class3.stopMe() 
      
      
      class Class3(threading.Thread): 
          def __init__(self): 
           threading.Thread.__init__(self) 
           self.stop = False 
      
          def stopMe(self): 
           self.stop = True 
      
          def run(self): 
           while not self.stop: 
            time.sleep(1) 
            print("{} stop status:{:6}".format(self.__class__, str(self.stop))) 
      
      
      class1 = Class1() 
      class1.start() 
      time.sleep(10) 
      class1.stopMe() 
      
    +0

    ありがとうthe threading.Lock example for print;) "whileブレークのあるif文ではなくself.stopではなくwhileの使用" stopはBeforeブロックBefore Trueを取得すると実行されません。これは望ましくない。 "Class3でのスレッドの使用"は望ましくないため、スレッドではありません。これは単なるサンプルコードでした:) –

    +0

    'foo'をクラス構造の外で定義し、新しいオブジェクトをインスタンス化するのではなく、' class2'から呼び出すことができますか?また、 'Class3'をスレッド化できないのはなぜですか?それは漬け物ではないものに作用していますか?ループを 'Class3.foo()'の中に入れるのではなく、 'True:\ n class3.foo()'を実行することができますか? 'class2.stop'と' Class2.stopC3'を定義するには、他の操作が 'class3'を止めるならば。また、私は息をする必要があります。 (比喩的に、とにかく...) – speedstyle

    関連する問題