当类中的其他方法仍在使用Python中的类成员时,更新该类成员的方法是什么?在
我希望类的其余部分继续使用成员的旧版本进行处理,直到它完全更新,然后在更新完成后将所有处理切换到新版本。在
下面是一个有趣的例子来说明我的用例,其中self.numbers
是需要使用updateNumbers()
中的逻辑进行安全线程化定期更新的类成员,我希望runCounter()
以非阻塞方式调用它。在
from time import sleep, time
class SimpleUpdater(object):
def __init__(self):
self.i = 5
self.numbers = list(range(self.i))
self.lastUpdate = time()
self.updateDelta = 10
def timePast(self):
now = time()
delta = self.lastUpdate - now
return (delta > self.updateDelta)
def updateNumbers(self):
print('Starting Update', flush=True)
self.numbers = list(range(self.i))
# artificial calculation time
sleep(2)
print('Done Updating', flush=True)
def runCounter(self):
for j in self.numbers:
print(j, flush=True)
sleep(0.5)
self.i += 1
if self.timePast:
## Spin off this calculation!! (and safely transfer the new value)
self.updateNumbers()
if __name__ == '__main__':
S = SimpleUpdater()
while True:
S.runCounter()
期望的行为是,如果self.numbers
在循环中被迭代,它应该在切换到新版本之前用旧版本完成循环。在
您可以为对
updateNumbers
的每次调用创建一个新线程,但是这种类型的更常见的方法是让1个线程在后台运行一个无限循环。您应该编写一个具有无限循环的方法或函数,该方法/函数将作为后台线程的目标。这种线程通常是一个守护进程,但它不是必须的。我修改了您的代码,以展示如何实现这一点(我还修复了示例代码中的一些小错误)。在请注意,我没有使用任何锁:)。{{{I>在不使用任何cdi}属性的情况下,都只能使用self.numbers的每个赋值都将一个新的
Numbers
对象与该属性相关联。每次访问该属性时,您应该期望得到一个不同的对象,但是如果您在方法的开头对该对象进行本地引用,即numbers = self.numbers
,numbers
将始终引用同一个对象(直到它在方法末尾超出作用域),即使后台线程更新了self.numbers
。在我创建一个
Numbers
类的原因是,我可以在单个(原子)赋值(数字列表和lastUpdated值)中获取和设置所有“volatile”成员。我知道这有很多需要跟踪的地方,老实说,使用锁可能更聪明、更安全:),但我也希望向您展示这个选项。在创建一个锁以控制对列表的访问:
当你需要保存一个本地列表时,保存一个本地变量。局部变量不会受实例属性更新的影响;请使用局部变量,直到要检查更新的值:
^{pr2}$每当您需要更新列表时,请按住锁并用新列表替换该列表,而不要更改旧列表:
顺便说一下,我在这里使用camelcase来匹配您的代码,但是Python的惯例是使用}作为变量和函数名。在
lowercase_with_underscores
而不是{相关问题 更多 >
编程相关推荐