Python 通过线程类传递变量

Python 通过线程类传递变量,python,multithreading,Python,Multithreading,在下面的测试代码中 class1.stop\u callback()设置class1.stop=True 因此class2.stop=True 因此class3.stop应该是真的,但事实并非如此 stop_callback()应该停止程序,但它不会这样做。 我做错了什么 您可以在repl.it上测试代码 在Python中,变量是对象的名称。通过将False分配给class1.stop和class1.stop分配给class2.stop,您将False分配给class2.stop,仅此而已 您似

在下面的测试代码中

class1.stop\u callback()设置class1.stop=True

因此class2.stop=True

因此class3.stop应该是真的,但事实并非如此

stop_callback()应该停止程序,但它不会这样做。 我做错了什么

您可以在repl.it上测试代码


在Python中,变量是对象的名称。通过将
False
分配给
class1.stop
class1.stop
分配给
class2.stop
,您将
False
分配给
class2.stop
,仅此而已

您似乎想要的是引用
class1.stop
,但这不是Python中赋值的工作方式。解决这个问题的一种方法是使用列表。如果保持列表不变,并且只更改第一个索引处的值,则可以实现您想要的:

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

由于
Class3
不是类
线程的类(尽管未在主线程中运行),因此无法更改
Class3的值。请停止
,直到
Class3.foo()
返回。由于
class3.foo()
class3.stop
的值更改之前不会返回,因此无法停止进程,它将永远运行

我建议将
Class3
建立在
Thread
上,这样您就可以在它运行时调用它的方法。如果这是太多的开销,或者每个
class2
实例将运行它不止一次,那么您总是可以定义
foo
,然后在
class2.run
方法中运行它


编辑:我本想提到Florian的观点,但由于——正如他提出的解决方案中所述——可变对象确实会在作业中传递,我不确定您是否已经仔细考虑了这一部分

以下是修订后的代码;注

  • 使用
    threading.Lock
    来防止在同一行上出现那些奇怪的打印语句
  • 使用
    而不是self.stop
    而不是
    if
    语句和
    break
    s
  • Class3


您正在将
class1.stop
设置为
True
在您已经复制了
class1.stop
的值之后。stop
设置为
class2.stop
。我是不是忽略了什么?或者您是否想使用
class2.stop
作为对
class1.stop
的一种引用?您想要的输出是什么,您希望程序做什么?@PrestonM“因此class3.stop应该是真的,但不是。”这就是问题所在,输出并不重要。@floriarhiem class1.stop\u callback()应该停止程序,但它没有这样做,因为class3.foo()没有得到self.stop=True值。你可以在Class2中测试代码,这里有一行“class3.stop=self.stop”,所以我将class1.stop指定给Class2.stop指定给class3.stop请再次阅读第一句话。通过将
class1.stop
赋值给
class2.stop
,您将其当前值
False
赋值给
class2.stop
。现在我明白了:)谢谢!感谢您提供的线程。打印锁定示例;)“使用while not self.stop而不是带有中断的if语句”如果stop在while块之前变为True,则不会执行。这不是我们想要的。“在类3中使用线程”是不需要的,它必须不是线程。这只是一个示例代码:)您能在类结构之外定义
foo
,然后从
class2
调用它,而不是实例化一个新对象吗?另外,为什么
Class3
不能被线程化?它是作用于不能腌制的东西吗?如果为True,您是否可以执行
:\n class3.foo()
,而不是将循环放入
class3.foo()
?如果其他操作要停止,则可以定义
Class2.stop
Class2.stopC3
。还有,我需要呼吸一下。(无论如何,隐喻性地…)
stop1 = [False]
stop2 = stop1
assert stop2[0] == False
stop1[0] = True
assert stop2[0] == True
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()