Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_Class_Inheritance_Instance - Fatal编程技术网

在Python中,线程之间共享类实例数据和方法,但只共享一个特定变量

在Python中,线程之间共享类实例数据和方法,但只共享一个特定变量,python,multithreading,class,inheritance,instance,Python,Multithreading,Class,Inheritance,Instance,拥有一个初始化的类实例,我需要在线程之间共享所有的实例数据和方法,只有一个变量,在所有线程之间有不同的结果,但要利用初始化的数据。我需要从实例到那个“私有”变量的所有类方法 class A(): def __init__(self): self.init_data = self._initialize() <- same for each thread self.a = 0 <- private for each thread

拥有一个初始化的类实例,我需要在线程之间共享所有的实例数据和方法,只有一个变量,在所有线程之间有不同的结果,但要利用初始化的数据。我需要从实例到那个“私有”变量的所有类方法

class A():

    def __init__(self):
        self.init_data = self._initialize()   <- same for each thread
        self.a = 0   <- private for each thread 

    def _initialize(self):
        # Get data from db (high cost)

    def calculate_a(self, data):
        # Calculate 'a' result from init_data to private 'a' variable

class ThreadClass(threading.Thread):

    # Inheritance? 
    # Pass instance as a init parameter and change somehow 'a' variable pointer? 


a = A()
t1 = ThreadClass(a)
t2 = ThreadClass(a)
t1.start()
t2.start()
t1.calculate_a(data1)
t2.calculate_a(data2)
t1.a <- some result1
t2.a <- some result2

可能吗?有人能给我一个有效的解决方案吗

一种方法是创建一个新类,该类继承自,并将昂贵的init_数据作为类属性。下面是一个源于您的代码的简短演示

class A:
    def __init__(self):
        self.init_data = self._initialize()   # <- same for each thread
        self.a = 0   # <- private for each thread 

    def _initialize(self):
        # Get data from db (high cost)
        print('_initialize called')
        return 1000

    def calculate_a(self, data):
        # Calculate 'a' result from init_data to private 'a' variable
        self.a += self.init_data + data

class MyA(A):
    # Create a single instance of the original class and store its 
    # init_data as a class attribute of MyA
    init_data = A().init_data

    # Get rid of the inherited  _initialize method
    _initialize = None

    # Override the inherited __init__
    def __init__(self):
        self.a = 0

# Test

b = MyA()
b.calculate_a(10)
print(b.a)
c = MyA()
c.calculate_a(100)
print(c.a)
b.calculate_a(20)
print(b.a)

如您所见,在定义MyA类时,只调用一次初始化。MyA的所有实例都共享MyA.init_数据,MyA的任何方法,包括从A继承的方法,在引用self.init_数据时都将使用该MyA.init_数据。

可以将init_数据设为类属性,以便所有实例共享它。我无法修改类,因为它是“pyknow”模块。这是我用来展示示例的一个最小化类,但涉及到很多类变量,不仅仅是init_data.Ok。即使A类是在另一个模块中定义的,您也可以通过在导入后对其进行monkey修补来做您想做的事情。然而,创建一个新类可能更简单更干净,如我的答案所示。顺便说一句,在代码中,init_数据是一个实例属性。将其称为类变量有点令人困惑,因为它听起来像是类属性。类属性由类的所有实例共享,实例属性不共享。您能告诉我类的所有实例共享的类变量是否在所有线程中共享吗?@variable如果类在全局范围内,则其类属性在所有线程中都可见。谢谢让我给您一个exmaple。在Flask中,如果我通过pip安装xyz安装包。然后,在route.py中导入xyz。然后,在路由功能中,如果我通过xyz.varname.append或xyz.varname=100在xyz中分配或变异变量。现在,这会影响所有其他用户线程中的varname吗?这很危险,不是吗?如果我错了,请纠正我。Thanks@variable对不起,我不知道,我也不明白你的评论与这个答案有什么关系。
_initialize called
1010
1100
2030