4

わかりました。私のプロジェクトの 1 つでかなり奇妙な動作がありました。誰かが理由を教えてくれることを願っています。私のファイル構造は次のようになります。

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

MainFrame.py の内部で、wx.Frame を拡張する RPMWindow という名前のクラスを定義しました。

MainApp.py では、次のように動作します。

from res.elements.MainFrame import *

そして、これはしません:

from res.elements.MainFrame import RPMWindow

ワイルド カード インポートが問題を起こさないことはわかっていますが、ワイルド カードが成功したときに名前付きインポートが失敗する理由を理解したいと思っています。

クラス名を使用すると、次のトレースバックが表示されます。

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

ワイルド カード インポートを使用すると、トレースバックが表示されず、アプリケーションが開きます。

4

3 に答える 3

8

循環インポートがあります:

MainFrame.py は MainApp.py を間接的にインポートしており、MainApp.py は MainFrame.py をインポートしています。その結果、MainApp.py が MainFrame.py をインポートしているときに、RPMWindow クラスがまだ定義されておらず、ImportError が発生します。

于 2010-04-19T18:02:45.343 に答える
0

ワイルドカードが機能している理由を調べる時間はありませんが、名前の直接インポートの失敗について言えることは、コードにインポートサイクルがあるということです:

をインポートしようとしていますが、そのコードres.elements.MainFrameの一部がインポートしようとしており、再度インポートしようとしています。IOW さん、最初のインポートの試みはまだ完了していません。もう一度試してください。res.elements.MenuBarres.elements.MainFrameres.elements.MainFrame

于 2010-04-19T18:07:09.437 に答える
0

コードに循環インポートがあります。同じモジュールが、特定の他のモジュールに必要であり、その使用を必要としています。そのように考えると、明らかに不安定です。ほとんどの問題は、または の代わりにを使用しimport a、後で参照することで解決できます。a.bfrom a import bfrom a import *

特に、絶対に使用しないfrom a import *でください。ワイルドカード インポートは名前空間を乱雑にし、コードの保守性、可読性、正気性、予測性を低下させます。import aとの違いfrom a import *は、ボックスを部屋にドラッグすることと、その中身を床全体に注ぐことの​​違いです。

共有コードを独自のモジュールに移動するか、何らかの方法で循環インポートの必要性をリファクタリングできるとよいでしょう。循環インポートは、常に設計上の問題を示しています。

于 2010-04-19T18:07:34.387 に答える