简体   繁体   English

Python通配符导入Vs命名导入

[英]Python Wildcard Import Vs Named Import

Ok, I have some rather odd behavior in one of my Projects and I'm hoping someone can tell me why. 好吧,我的一个项目中有一些相当奇怪的行为,我希望有人可以告诉我原因。 My file structure looks like this: 我的文件结构如下所示:

MainApp.py
res/
  __init__.py
  elements/
    __init__.py
    MainFrame.py

Inside of MainFrame.py I've defined a class named RPMWindow which extends wx.Frame. 在MainFrame.py中,我定义了一个名为RPMWindow的类,它扩展了wx.Frame。

In MainApp.py this works: 在MainApp.py中,这有效:

from res.elements.MainFrame import *

And this does not: 而这不是:

from res.elements.MainFrame import RPMWindow

I realize that the wild card import won't hurt anything, but I'm more interested in understanding why the named import is failing when the wild card succeeds. 我意识到外卡导入不会伤害任何东西,但我更感兴趣的是理解为什么命名导入在外卡成功时失败。

When using the class name I get this traceback: 使用类名时,我得到了这个回溯:

Traceback (most recent call last):
  File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 953, in <module>
    debugger.run(setup['file'], None, None)
  File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 780, in run
    execfile(file, globals, locals) #execute the script
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
    from res.elements.MainFrame import RPMWindow
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MainFrame.py", line 2, in <module>
    from res.elements.MenuBar import MenuBarBuilder
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MenuBar.py", line 2, in <module>
    from MainApp import _, DataCache
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
    from res.elements.MainFrame import RPMWindow
ImportError: cannot import name RPMWindow

When using the wild card import I don't receive a traceback and my application opens. 使用通配符导入时,我没有收到回溯,我的应用程序打开。

You have circular imports: 你有循环进口:

MainFrame.py is indirectly importing MainApp.py, and MainApp.py is importing MainFrame.py. MainFrame.py间接导入MainApp.py,MainApp.py正在导入MainFrame.py。 As a result, when MainApp.py is importing MainFrame.py, the RPMWindow class hasn't been defined yet and you get the ImportError. 因此,当MainApp.py导入MainFrame.py时,RPMWindow类尚未定义,您将获得ImportError。

i don't have time to look into why the wildcard is working for you, but what i can say about your failure with the direct name import is that you have an import cycle in your code: 我没有时间研究为什么通配符适合你,但我可以说你的直接名称导入的失败是你的代码中有一个导入周期:

you are trying to import res.elements.MainFrame , but part of that code is trying to import res.elements.MenuBar which tries to import res.elements.MainFrame again. 您正在尝试导入res.elements.MainFrame ,但代码的一部分是尝试导入res.elements.MenuBar ,它res.elements.MainFrame再次尝试导入res.elements.MainFrame IOW, your first attempt to import res.elements.MainFrame has not completed yet before you try it again. IOW,您再次尝试导入res.elements.MainFrame之前的第一次尝试尚未完成。

You have circular imports in your code: the same module is both required by and requires the use of a certain other module, which when you think of it like that, it clearly precarious. 你的代码中有循环导入:同一个模块都是必需的,并且需要使用某个其他模块,当你想到它时,它显然是不稳定的。 Most of the problems can be cleared up by using import a and later referring to ab instead of from a import b or from a import * . 大多数问题可以通过使用import a和后来引用ab而不是from a import bfrom a import *来清除。

In particular, never use from a import * . 特别是, 永远不要使用from a import * Wildcard imports clutter your namespace and makes your code less maintainable, readable, sane, and predictable. 通配符导入会破坏您的命名空间,使您的代码不易维护,可读,理智且可预测。 The difference between import a and from a import * is the difference between dragging a box into a room and pouring its contents all over the floor. import afrom a import *之间的区别是将盒子拖入房间并将其内容倒在地板上之间的区别。

It would be better if you could move shared code off to its own module or somehow refactor out the need for a circular import. 如果你可以将共享代码移动到它自己的模块或以某种方式重构循环导入的需要会更好。 Circular imports always indicate a design problem. 循环导入始终表示设计问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM