3

次の 2 つのモジュール、prog.py と err.py について考えてみましょう。どちらも、この問題を示す大規模なプログラムの例です。機能を小さなソース ファイルに分割し、それぞれにテスト ベンチを配置する必要があります。

Err.py にはテスト ベンチが含まれています。prog オブジェクトを作成すると、例外の呼び出し方法に応じて、例外がキャッチされるかどうかが決まります。

prog.py が「from err import *」ステートメントで err オブジェクトをインポートしても、モジュール名はまだ推測されているようですが (間違っていますか?)、それが参照する err はモジュール自体と同じものではないようです。

これは Python 2.7 のバグですか、それとも意図した動作ですか?

両方のファイルを取得して err.py を実行するだけで、私の言いたいことがわかります..

最初のファイル:

#prog.py

from err import *



class prog(object):
    def func1(self):
        raise MySubError

    def func2(self):
        doError()

そして2番目のファイル:

#err.py
import prog
import inspect
import sys

class myError(Exception):
    pass

class MySubError(myError):
    pass

def doError():
    raise MySubError

if __name__=="__main__":

    p=prog.prog()


    try:
        doError()
    except MySubError as er:
        print type(er)
        print "Captured 1"
    except Exception as er:
        print type(er)
        print "Not Captured 1"        

    try:
        p.func1()
    except MySubError as er:
        print type(er)
        print "Captured 2"
    except Exception as er:
        print type(er)
        print "Not captured 2"


    try:
        p.func2()
    except MySubError as er:
        print type(er)
        print "Captured 3"
    except Exception as er:
        print type(er)
        print "Not captured 3"

どうにかして err はそれがどのモジュールであるかを知る必要があり、例外は単に MySubError ではなく err.MySubError である必要があるように私には思えます。モジュールは取得できますが、インスタンスは取得できません.....

出力:

<class '__main__.MySubError'>
Captured 1
<class 'test.MySubError'>
Not captured 2
<class 'test.MySubError'>
Not captured 3
4

2 に答える 2

2

ここでの問題は、err実際には 2 つの異なるモジュールとして機能することです。

Python で実行されるメイン モジュールは と呼ばれ__main__ます。実行されたものはすべてその名前空間に入れられます。ここで起こっていることは、モジュールを他のスクリプトにインポートしていて、それが呼び出されerrているため、同じとは見なされないということです。

これは少し奇妙ですが、Python インポート システムの動作の一貫性を維持する必要があります。ここでの最良の答えは、例外を として呼び出されるスクリプトの外に移動すること__main__です。基本的にここで循環インポートを作成しているため、これはとにかく良い設計です。

于 2012-04-29T15:04:22.773 に答える
1

err.py問題は、Python がメイン スクリプトと同じであることを認識していないことです。通常、モジュールは 1 回だけインポートされますが、メイン スクリプト自体がモジュールとしてインポートされると、python が混乱し、実際にはerr.py2 回読み込まれます。(私はその正当な理由を認識していません。@Latty の方がより具体的である可能性があります)。

この単純なスクリプトで問題を確認できます。

# File: recur.py
import recur
print "This is the module"

if __name__ == '__main__':
    print "This is main"

モジュールは一度しかインポートされないため、実行すると無限再帰は発生しません。ただし、「これはモジュールです」が 2 回表示されます。

メイン スクリプトがそれ自体を (直接的または間接的に) インポートしない限り、あるモジュールから別のモジュールに例外をインポートしても問題はありません。また、相互に依存する 2 つのモジュール A と B があり、それぞれが他方をインポートしても問題はありません。試してみるimport Aと、それぞれが 1 回だけロードされることがわかります。

編集:メインスクリプトをモジュールとしてインポートすることは避けるべきだと本当に思いますが、あなたの例の修正を考えました:

# err.py
...
if __name__=="__main__":
    from prog.err import *     # add this line

これにより、重複するすべてのスクリプト クラスがそれぞれのモジュール バージョンに置き換えられ、すべてが意図したとおりに機能します。

于 2012-04-29T15:25:57.567 に答える