Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 模块在没有明确指令的情况下重新加载和重置_Python 3.x_Module_Pygame - Fatal编程技术网

Python 3.x 模块在没有明确指令的情况下重新加载和重置

Python 3.x 模块在没有明确指令的情况下重新加载和重置,python-3.x,module,pygame,Python 3.x,Module,Pygame,TLDR:我想知道,一般来说,什么会导致模块重新加载并重置回原始状态,而无需我明确尝试使其恢复。 我得出的结论是,我的主模块正在重新加载,在此过程中,所有变量都被重新初始化为初始状态 我不能给出一个最小的可重复的例子。在谷歌搜索之后,我找不到关于这个主题的任何其他东西,除了python3.x不应该重新加载模块,除非明确要求 使用PyGame1.9.6 我想问一下,通常是什么导致了这种行为。添加调试打印的主模块示例: import pygame from sys import exit clas

TLDR:我想知道,一般来说,什么会导致模块重新加载并重置回原始状态,而无需我明确尝试使其恢复。

我得出的结论是,我的主模块正在重新加载,在此过程中,所有变量都被重新初始化为初始状态

我不能给出一个最小的可重复的例子。在谷歌搜索之后,我找不到关于这个主题的任何其他东西,除了python3.x不应该重新加载模块,除非明确要求

使用PyGame1.9.6

我想问一下,通常是什么导致了这种行为。添加调试打印的主模块示例:

import pygame
from sys import exit

class Engine:
    def __init__(self):
        self.init = False
        self.running = False

    def start(self):
        print("engine start called")
        print("self.init state:", self.init)        

        from graphics import render
        render.init()

        from initializer import initializer
        initializer.init_sprites()

        if not self.init:
            self.init = True
            self.running = True

        print("new self.init state:", self.init)

        self.main_loop()

    def update_input(self):
        pass

    def update_events(self):
        pass

    def update_graphics(self):
        pass

    def self.main_loop() # it's at the very end of the real Engine() aswell
        while True:
            self.update_input()
            self.update_events()
            self.update_graphics()

        pygame.quit()
        exit()


engine = Engine()

print("above engine start reached")

app_init = False # I added this purely for debugging reasons

if not app_init:
    app_init = True
    engine.start()

该应用程序没有崩溃或抛出异常,因为所有其他模块都在正常运行。例如,精灵保持其状态,并保持其应有的移动。相机仍然可以滚动et c

但是,console提供:

above engine.start() reached
engine start called
self.init state: False
render.init called
new self.init state: True
#stuff happening in background in other modules, no methods changing self.running or explicitly reloading main module. However imports of engine object do happen
above engine.start() reached
engine start called
self.init state: False
render.init called
new self.init state: True
但是:

1) main_loop()永远不会返回到

2) 打印结果证明,即使While循环应该处于活动状态,主模块的末尾也会以某种方式到达,并且如果应用程序在main_loop()中移动超过While循环,则应退出()

3) self.init和global app_init状态重置为硬编码值,并调用engine.start(),就像第一次初始化模块一样

这是一个进口问题吗

更新:


没有解决。但是我通过阻止所有其他模块重新初始化,消除了所有副作用。然而,这似乎是一个肮脏的黑客行为,我担心重新加载我的主模块迟早会导致后果。

这基本上是一个猜测,但我可以想象的唯一解释是,根据提供的信息,您的一些“其他模块”会导入您的文件。如果是这种情况,您应该重新构造代码以避免循环依赖。检查这一点的一个简单方法是添加一个保护,防止在导入时执行类定义下的所有内容:

class Engine:
    # ...


if __name__ == "__main__":

    engine = Engine()

    print("above engine start reached")

    app_init = False # I added this purely for debugging reasons

    if not app_init:
        app_init = True
        engine.start()
另外,请将您的导入(在
引擎中的导入。\uuu init\uuu
)移动到模块的顶层

编辑

导入是问题所在(我在另一个模块中从引擎检索deltatime)

设计问题

删除该导入后,引擎不再重新初始化。我现在使用if name==“main”。(…)导入模块时,我不知道底部的engine=engine()会重新初始化引擎

Python是一种运行时语言——除了字节码编译,一切都发生在运行时。第一次加载Python模块时(在给定的过程中),将执行模块顶层的所有代码-这就是创建函数和类的方式(
def
class
是可执行语句)等-然后将其缓存在
sys.modules
dict(在模块名称下)中以进行其他导入(所以只加载了一次)

现在,当一个模块用作脚本时,也会发生同样的情况,只是该模块以
\uuuu main\uuuu
的名称导入(并缓存)。因此,当其他模块尝试导入主脚本时,加载程序会查找脚本名,但找不到它(因为它被缓存为“main”,而不是“youscriptname”),然后重新加载。这解释了双重加载,但也意味着这两个模块是不同的实例,类是不同的类,“引擎”实例是不同的实例

注意,虽然
if\uuuuu name\uuuu='\uuuuu main\uuuu'
保护程序阻止脚本的“main”代码执行两次,但您只是掩盖了症状,没有修复根本问题。长话短说,您的任何模块都不应该尝试访问主脚本中定义的任何内容


如果主脚本中定义了要在其他地方重用的函数或类,则应将它们提取到另一个模块。但是,如果另一个模块中的某些内容需要从主脚本访问
引擎
实例,则必须重新考虑设计,以明确地传递
引擎
实例(或需要的任何内容)。

还应该注意,
def-self.main_-loop()
应该是
def-main_-loop(self):
@mkusz确实是这样-但这显然是在这里发布时的一个拼写错误,否则OP会有错误;-)这是我的想法,但也很好,只是为了确保:)谢谢大家的回答。导入是问题所在(我在另一个模块中从引擎检索deltatime)。删除该导入后,引擎不再重新初始化。我现在使用if name==“main”。关于文件顶部的导入,我将对此进行更改,从今以后再这样做。我很惊讶,一个人能用Python的初级知识(me)完成多少工作。我不知道在导入模块时,底部的engine=engine()会重新初始化引擎。太棒了。这避免了这样的麻烦。在对每个模块顶部的导入进行重新构造并确保每个帧都没有执行导入之后(我感到惭愧),另一个我没有意识到的问题得到了解决。对于我在Python方面水平较低的其他读者;请务必阅读上面的标记答案!1/您如何运行代码?2/是否有其他模块导入此模块?如果是,请编辑您的帖子,以显示您的源目录布局和这些导入。哦,是的:这种情况会发生很多次还是只发生一次?“我已经通过防止所有其他模块重新初始化消除了所有副作用”=>你是什么意思?