Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 具有可变类型参数的多线程函数_Python_Multithreading_Mutable - Fatal编程技术网

Python 具有可变类型参数的多线程函数

Python 具有可变类型参数的多线程函数,python,multithreading,mutable,Python,Multithreading,Mutable,这段代码没有用[0]-[9]序列显示正确的结果,但所有结果都是[9]。但是,如果将其更改为thread_list.appendthreading.Threadtarget=Atupleindex.run 或者直接启动,而不是在另一个循环中启动,或者将索引定义放在循环中,这样结果就可以了。 下面是另外两个正确的版本: import threading, time class A(): def __init__(self,a ): self.a = a def ru

这段代码没有用[0]-[9]序列显示正确的结果,但所有结果都是[9]。但是,如果将其更改为thread_list.appendthreading.Threadtarget=Atupleindex.run 或者直接启动,而不是在另一个循环中启动,或者将索引定义放在循环中,这样结果就可以了。 下面是另外两个正确的版本:

import threading, time
class A():
    def __init__(self,a ):
        self.a = a

    def run(self):
        print(self.a)

if __name__=='__main__':
    index = [0]
    thread_list = []
    for i in range(10):
        index[0] = i
        thread_list.append(threading.Thread(target=A(index).run))
    for thread in thread_list:
        thread.start()
        time.sleep(0.5)

    for thread in thread_list:
        thread.join()

有人可以解释Python初始化线程对象和调用start方法背后的机制。当可变变量传递到函数中时,为什么总是最后一个呢?

您的第一段代码之所以这样做,是因为您在创建每个a类实例时正在传递一个名为index的可变对象列表,因此,当它们打印其值时,它们都会显示其中当前的内容,这将是在下一行中创建线程实例之前分配给索引[0]的最后一个内容

因此,解决方法是避免将函数传递给可变对象。下面是一个简单的方法:

import threading, time
class A():
    def __init__(self,a ):
        self.a = a

    def run(self):
        print(self.a)

if __name__=='__main__':

    thread_list = []
    for i in range(10):
        index = [0]
        index[0] = i
        thread_list.append(threading.Thread(target=A(index).run))
    for thread in thread_list:
        thread.start()
        time.sleep(0.5)

    for thread in thread_list:
        thread.join()

谢谢你的帮助。我还有一个问题。当通过threading.Threadtarget=Aindex.run初始化对象A时,A的实例不像深度复制或返回值那样固定,它的行为更像list.append?在Python中传递可变对象时,它实际上传递的是对对象的引用,而不是对象的副本。然后将该引用指定给调用的函数或方法的命名参数。如果你想复印件通过,你必须自己制作。代码中最简单的方法是使用threading.Threadtarget=Aindex[:]。运行添加的[:]将创建整个列表的副本,而不仅仅是我当时回答中的第一个元素,并将该副本作为参数值传递。
import threading, time
class A():
    def __init__(self,a ):
        self.a = a

    def run(self):
        print(self.a)

if __name__=='__main__':

    thread_list = []
    for i in range(10):
        index = [0]
        index[0] = i
        thread_list.append(threading.Thread(target=A(index).run))
    for thread in thread_list:
        thread.start()
        time.sleep(0.5)

    for thread in thread_list:
        thread.join()
class A():
    def __init__(self, a):
        self.a = a

    def run(self):
        print(self.a)

if __name__=='__main__':
    index = [0]
    thread_list = []
    for i in range(10):
        index[0] = i
#       thread_list.append(threading.Thread(target=A(index).run))
        thread_list.append(threading.Thread(target=A(index[0]).run()))
    for thread in thread_list:
        thread.start()
        time.sleep(0.5)

    for thread in thread_list:
        thread.join()