类在sys.modules中,但不能使用。为什么?

时间:2015-10-19 10:59:27

标签: python

我有一个文件MySQL.py,其中包含一个如此定义的类MySQL

class MySQL:
    ... all stuff that is not important here

在其他文件(test.py)中,我在同一目录中对这个MySQL类进行了条件加载。通过这个条件加载我的意思是,我加载它以防它尚未加载。要检查它,我使用sys.modules,如下所示:

print("MySQL" not in sys.modules)
if "MySQL" not in sys.modules:
    from MySQL import MySQL
    print("Loaded it")
    print("MySQL" not in sys.modules)
return MySQL()

如您所见,我有一些print's用于调试目的。当我运行这个文件时,这就是我在控制台中得到的结果:

$ python3 test.py
True
Loaded it
False
Traceback ...
...
UnboundLocalError: local variable 'MySQL' referenced before assignment

这真的很有趣,因为在我们看到的控制台中,首先没有加载模块(print("MySQL" not in sys.modules) => True),然后我们看到它被加载,但最后是一些疯狂的原因Python没有看到这个课程。 PS。我应该补充一点,如果我在文件的最开头导入(在所有其他代码之前,那么一切正常)。

修改

我想,我明白了,所有麻烦的全部原因是我的方式import将我的课程设置为sys.modules,但同时它将它放到本地命名空间函数而不是模块的全局命名空间。那就是它。

1 个答案:

答案 0 :(得分:1)

您的代码无效,因为如果先前已加载<h:panelGroup id="newchargeBlock" layout="block"> <div class="modal fade bs-example-modal-lg" id="newchargemodal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> New Charge modal </div> <div class="modal-body"> <h:panelGrid columns="4" > <f:view> <h:form id="newregtype"> <h:outputLabel for="chargename" value="xy:"></h:outputLabel> <h:inputText value="#{mainViewController.newChargeTypeName}" id="chargename" styleClass="form-control"></h:inputText> <h:outputLabel for="chargename" value="xy:"></h:outputLabel> <h:selectOneMenu value="#{mainViewController.newChargeTypeGroupId}" styleClass="form-control"> <f:selectItems var="item" itemLabel="#{item.groupName}" itemValue="#{item.id}" value="#{mainViewController.showAllChargeGroup()}"></f:selectItems> </h:selectOneMenu> <p:commandButton ajax="true" process="newregtype" actionListener="#{mainViewController.createNewIncomingChargeReg()}" value="Save" ></p:commandButton> </h:form> </f:view> </h:panelGrid> </div> </div> </div> </div> </h:panelGroup> 模块,则您不会导入该类,因此尝试在最后一行调用MySQL无法工作。

更好的方法是无条件地进行导入。 Python一旦加载就会缓存该模块(这是MySQL()的全部目的),所以如果你不止一次导入它,你在其中的重量级代码仍将只运行一次。 / p>

也就是说,如果你的模块在顶层做了很多事情,这可能是设计糟糕的表现。也许你应该移动一些或所有对象创建或某个函数内的任何东西,并在适当的时候调用它。