在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