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

时间:2018-04-25 08:24:49

标签: 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 

    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

这可能吗?有人能给我任何有效的解决方案吗?

1 个答案:

答案 0 :(得分:1)

这样做的一种方法是创建一个继承自A的新类,并将昂贵的init_data作为类属性。这是一个源自您的代码的简短演示。

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)

<强>输出

_initialize called
1010
1100
2030

如您所见,A._initialize()仅在定义MyA类时被调用一次。 MyA的所有实例都共享MyA.init_dataMyA的所有方法(包括它从A继承的方法)都会在{{1}时使用MyA.init_data引用。