在concurrent.futures线程中使用class属性

时间:2017-10-28 18:54:05

标签: python multithreading oop attributes concurrent.futures

如何在调用其他方法的线程中使用某些类属性而不编辑初始值并且不将该属性作为参数传递?

“First”和“second”值必须始终等于“init”值,“third”和“4th”必须相等。

此示例显示了最初的问题:

from concurrent.futures import ThreadPoolExecutor
from random import random
from time import sleep

class main():
    def __init__(self):
        self.var = random()
        print('init', self.var)

    def first(self):
        print('first', self.var)
        self.second()
        print('fourth', self.var)

    def second(self):
        print('second', self.var)
        self.var = random()
        print('third', self.var)
        sleep(1)

m = main()
with ThreadPoolExecutor() as executor:
    executor.submit(m.first)
    executor.submit(m.first)
    executor.submit(m.first)

使用该方法将 self.var 分配给另一个属性显然不起作用:

class main():
    def __init__(self):
         self.var = random()
         print('init', self.var)

    def first(self):
         self.var2 = self.var
         print('first', self.var2)
         self.second()
         print('fourth', self.var2)

    def second(self):
        print('second', self.var2)
        self.var2 = random()
        print('third', self.var2)
        sleep(1)

我尝试的唯一解决方案是将属性分配给局部变量并将其作为参数传递给被调用函数。在我的情况下,这不是一个好的解决方案,因为我需要传递大量属性,代码会迅速增加,并且开始的可读性会降低。

class main():
    def __init__(self):
        self.var = random()
        print('init', self.var)

    def first(self):
        var = self.var
        print('first', var)
        var = self.second(var)
        print('fourth', var)

    def second(self, par):
        print('second', par)
        par = random()
        print('third', par)
        sleep(1)
        return par

你能想到使用属性的pythonic方法而不是作为参数传递的局部变量吗?

编辑: 我刚刚找到了解决问题的新方法:使用“非本地”语句并嵌套函数,您对此有何看法?

class main():
def __init__(self):
    self.var = random()
    print('init', self.var)

def first(self):
    var = self.var
    print('first', var)

    def second():
        nonlocal var
        print('second', var)
        var = random()
        print('third', var)
        sleep(1)

    second()
    print('fourth', var)

1 个答案:

答案 0 :(得分:3)

如果您只想为每个步骤设置单独的状态,则可以创建不同的对象并将其传递到每个线程中:

from concurrent.futures import ThreadPoolExecutor
from random import random
from time import sleep

class main():
    def __init__(self):
        self.var = random()
        print('init', self.var)

    def first(self):
        print('first', self.var)
        self.second()
        print('fourth', self.var)

    def second(self):
        print('second', self.var)
        self.var = random()
        print('third', self.var)
        sleep(1)

def worker():
    m = main()
    m.first()

with ThreadPoolExecutor() as executor:
    executor.submit(worker)
    executor.submit(worker)
    executor.submit(worker)