【问题标题】:Python: How to Encapsulate a Variable Across Multiple Classes?Python:如何跨多个类封装一个变量?
【发布时间】:2014-12-09 02:31:54
【问题描述】:

我有一个使用线程计时器的脚本,它随机操作 2 个常见列表。

因为类实例操作线程计时器上的列表,我无法将变量传递给类并返回。

…类的所有实例都需要操作一个单一的、最新的列表。

因此,这些列表的范围设置为全局。但是,我需要范围在类级别,但要被多个类操作。

澄清一下……

这是基本的程序结构:

Global list variable_1
Global list variable_2

class MasterClass:
    # this creates instances of the threaded classes. 
    There are 50+ instances of MasterClass creating thousands
    of instances of ThreadedClass1, 2, & 3.  All manipulate
    global list variables 1 & 2.

class ThreadedClass1:
    # threaded classes manipulate global list variables 1 & 2 on random timers.

class ThreadedClass2:

class ThreadedClass3:

问题:对于 MasterClass 的每个实例,我需要一个单独的列表变量 1 和 2。由该 MasterClass 实例调用的每个 ThreadedClasses 实例必须仅操作该 MasterClass 实例拥有的列表变量.

基本上我需要一个全局列表变量的等价物,但我需要它被 MasterClass 的一个实例封装,并由仅由该 MasterClass 实例调用的任何 ThreadedClasses 实例操作。

这是怎么做到的?

【问题讨论】:

    标签: python multithreading global


    【解决方案1】:

    如果我理解正确,您应该可以将它们设为MasterClass 的实例变量并将它们传递给构造函数。

    例如。

    class MasterClass:
        def __init__(self):
            self.variable_1 = [...]
            self.variable_2 = [...]
            self.tc1 = ThreadedClass1(self.variable_1, self.variable_2)
            self.tc2 = ThreadedClass2(self.variable_1, self.variable_2)
            self.tc3 = ThreadedClass3(self.variable_1, self.variable_2)
    

    或者将整个实例传入

    class MasterClass:
        def __init__(self):
            self.variable_1 = [...]
            self.variable_2 = [...]
            self.tc1 = ThreadedClass1(self)
            self.tc2 = ThreadedClass2(self)
            self.tc3 = ThreadedClass3(self)
    
    class ThreadedClass1:
        def __init__(self, parent):
            self.mc = parent
    

    等等

    【讨论】:

    • Variable_1 & 2 由数以千计的线程类实例在随机计时器上进行操作。如果我以这种方式传递变量,如何使它们保持同步?这意味着 Threadedclass 的一个实例更改了变量,然后将更改后的变量返回给 MasterClass,但在此期间,其他几个 Threadedclass 实例也更改了该变量。我需要以某种方式构建代码,以便所有引用实例和更改相同的变量。
    • 变量没有“返回”——它们是对同一个列表的引用。
    • 感谢 gnibbler……但我想我在这里遗漏了一些东西…………他们引用了相同的列表。但是当 ThreadedClass 对列表进行更改时呢? self.tc1 = ThreadedClass1(self.variable_1, self.variable_2) 据我了解,variable_1 & 2 的范围将处于 ThreadedClass 级别?对它们的任何更改只会在 ThreadedClass1 的实例范围内更改,而不会在 MasterClass 的范围内更改?还是我错过了什么?
    • 您误解了引用的工作原理。您最终会得到 4 个具有各自范围的变量/名称/引用,但它们都是对同一个列表的引用。列表对象本身没有范围 - 它只是一个对象。
    • 对不起。我不明白这个……简而言之…… MasterClass 的每个实例都会创建列表对象。 MasterClass 创建一个 ThreadedClass 的实例: self.tc1 = ThreadedClass1(self.variable_1, self.variable_2) 现在 ThreadedClass 持有这些变量。我们现在有 4 个变量。 2 在 MasterClass 的范围内和 2 在 ThreadedClass 的范围内。 ThreadedClass 对这些变量进行更改。如何让这些更改立即反映在 MasterClass 范围内的这些变量的值中?
    【解决方案2】:

    尝试将MasterClass 的实例传递给每个生成的ThreadedClasses 实例。

    然后,在MasterClass 中定义线程保存方法,它将使用您的variable_1variable_2 执行操作。 ThreadedClasses 不能直接接触这个列表,只能调用那些方法。

    小例子(查看subclassing from object):

    import threading
    
    
    class ThreadedClassBase(object):
        def __init__(self, master, *args, **kwargs):
            self.master = master
    
        def do_something(self):
            self.master.append(1, 'some_value')
            value = self.master.getitem(1, 0)
    
    
    class ThreadedClass1(ThreadedClassBase):
        def __init__(self, *args, **kwargs):
            super(ThreadedClass1, self).__init__(*args, **kwargs)
            # ...
    
    # same for ThreadedClass2, 3
    
    
    class MasterClass(object):
        def __init__(self, *args, **kwargs):
            self.variable_1 = list()
            self.variable_2 = list()
            self.lock = threading.Lock()
            for i in range(50):
                ThreadedClass1(master=self)
                # create new thread
    
        def append(list_nb, value):
            with self.lock:
                getattr('variable_' + list_nb).append(value)
    
        def getitem(list_nb, index):
            with self.lock:
                return getattr('variable_' + list_nb)[index]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-07
      • 2012-11-26
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      相关资源
      最近更新 更多