Python 多处理:在 child 中重新加载模块影响 parent
Python Multiprocessing: Reloading module in child effecting parent
我觉得我应该用以下声明作为这个问题的开头:我知道在 python 中重新加载模块是不受欢迎的。我更多的是在修补 Python 并做一些事情来证明我可以。
假设我在主文件中有这段代码:
def reloadFoo():
lastReloadedTime = time.time()
while True:
if os.stat(foo.__file__).st_mtime > lastReloadedTime:
lastReloadedTime = time.time()
reload(foo)
和foo.py包含
def printMe():
print "Yo ho yo ho"
如果我调用 reloadFoo()
,如果模块自上次重新加载后被修改,它将永远重新加载模块。但是我如何使它作为某种后台功能工作呢?
我研究了多处理,所以我在 main 中有这样的东西:
import foo
def reloadFoo():
....
reloadProc = multiprocessing.Process(target=reloadFoo)
reloadProc.start()
...
while True:
foo.printMe()
time.sleep(20)
但看起来如果我将 foo.py 的 printMe 更改为打印 "A Pirate's Life for Me",它会重新加载模块,但不会 "ripple" 到 parent进程(以及未来的 children):主循环仍然打印 "Yo ho yo ho"
我尝试将 Pipe 的一端发送到 reloadFoo,但我仍然不得不在 main 的 while 循环中调用 reloadFoo()(这违背了它有一个 child 进程开始的目的,我猜)。
实际问题:有没有办法让 child 进程重新加载模块并且它也在 parent 的进程(以及未来的 children)中重新加载?
一个child进程不能很容易地以这种方式直接影响它的parent。将 Python 添加到组合中,实际上不可能以一种可以满足您要求的方式进行操作。
你说你知道重新加载模块是不受欢迎的,你只是 "tinkering around",但你接着说 实际问题:有没有办法 [= =49=] 进程重新加载模块,它也会在 parent 的进程(以及未来的 children)中重新加载?
所以既然你已经问了这个问题,我将给出你无论如何都不想要的答案,因为 Stack Overflow 不仅仅是关于原始提问者:-)
重新加载模块并不因为美观而被反对;重新加载模块是不受欢迎的,因为在任何实际系统中,重新加载模块不太可能给你想要的东西,即使你没有尝试从不同的过程.
例如,让我们制作一个名为 reloadme.py 的简单模块:
class MyClass(object):
def __init__(self, value=0):
self.value = value
def __eq__(self, other):
return type(self) is type(other) and self.value == other.value
它有一个单独的 class 定义,这个 class 可以做的事情之一是允许它的实例查看它们是否等于它的其他实例。 (这本身就很不Pythonic,因为它没有使用鸭子类型,但它仍然是一个非常简单的方法来说明 real-world 问题 将 突然出现任何规模的系统。)所以让我们使用这个模块:
>>> import reloadme
>>> x = reloadme.MyClass()
>>> y = reloadme.MyClass()
>>> reload(reloadme)
>>> z = reloadme.MyClass()
>>> x == y
True
>>> x == z
False
即使您已经成功地重新加载了模块,系统中仍然存在旧模块的零碎信息。清理它们 真的 痛苦而且 time-consuming,不 清理它们会给你带来各种令人头疼的调试问题,让你产生疑问你自己的理智。
不过,可能 有很好的理由这样做,例如永远不会崩溃的系统。但这不是一件容易的事,而且大多数时候,它的效率不是很高。
我觉得我应该用以下声明作为这个问题的开头:我知道在 python 中重新加载模块是不受欢迎的。我更多的是在修补 Python 并做一些事情来证明我可以。
假设我在主文件中有这段代码:
def reloadFoo():
lastReloadedTime = time.time()
while True:
if os.stat(foo.__file__).st_mtime > lastReloadedTime:
lastReloadedTime = time.time()
reload(foo)
和foo.py包含
def printMe():
print "Yo ho yo ho"
如果我调用 reloadFoo()
,如果模块自上次重新加载后被修改,它将永远重新加载模块。但是我如何使它作为某种后台功能工作呢?
我研究了多处理,所以我在 main 中有这样的东西:
import foo
def reloadFoo():
....
reloadProc = multiprocessing.Process(target=reloadFoo)
reloadProc.start()
...
while True:
foo.printMe()
time.sleep(20)
但看起来如果我将 foo.py 的 printMe 更改为打印 "A Pirate's Life for Me",它会重新加载模块,但不会 "ripple" 到 parent进程(以及未来的 children):主循环仍然打印 "Yo ho yo ho"
我尝试将 Pipe 的一端发送到 reloadFoo,但我仍然不得不在 main 的 while 循环中调用 reloadFoo()(这违背了它有一个 child 进程开始的目的,我猜)。
实际问题:有没有办法让 child 进程重新加载模块并且它也在 parent 的进程(以及未来的 children)中重新加载?
一个child进程不能很容易地以这种方式直接影响它的parent。将 Python 添加到组合中,实际上不可能以一种可以满足您要求的方式进行操作。
你说你知道重新加载模块是不受欢迎的,你只是 "tinkering around",但你接着说 实际问题:有没有办法 [= =49=] 进程重新加载模块,它也会在 parent 的进程(以及未来的 children)中重新加载?
所以既然你已经问了这个问题,我将给出你无论如何都不想要的答案,因为 Stack Overflow 不仅仅是关于原始提问者:-)
重新加载模块并不因为美观而被反对;重新加载模块是不受欢迎的,因为在任何实际系统中,重新加载模块不太可能给你想要的东西,即使你没有尝试从不同的过程.
例如,让我们制作一个名为 reloadme.py 的简单模块:
class MyClass(object):
def __init__(self, value=0):
self.value = value
def __eq__(self, other):
return type(self) is type(other) and self.value == other.value
它有一个单独的 class 定义,这个 class 可以做的事情之一是允许它的实例查看它们是否等于它的其他实例。 (这本身就很不Pythonic,因为它没有使用鸭子类型,但它仍然是一个非常简单的方法来说明 real-world 问题 将 突然出现任何规模的系统。)所以让我们使用这个模块:
>>> import reloadme
>>> x = reloadme.MyClass()
>>> y = reloadme.MyClass()
>>> reload(reloadme)
>>> z = reloadme.MyClass()
>>> x == y
True
>>> x == z
False
即使您已经成功地重新加载了模块,系统中仍然存在旧模块的零碎信息。清理它们 真的 痛苦而且 time-consuming,不 清理它们会给你带来各种令人头疼的调试问题,让你产生疑问你自己的理智。
不过,可能 有很好的理由这样做,例如永远不会崩溃的系统。但这不是一件容易的事,而且大多数时候,它的效率不是很高。