2

Eclipse プラットフォーム、Python 3.3。

グローバル変数と python unittest を使用する際の問題を示すために、以下のコードを作成しました。2 番目の単体テスト (最初の単体テストの直接の繰り返し) の結果が

NameError: global name '_fred' is not defined

2 番目のテストをコメントアウトしてみてください。すべて問題なくパスします。
(注:実際のコードが達成しようとしているものの簡単なダイジェストを例の後に追加しました。問題とはあまり関係がないので、邪魔にならないように願っています)

''' Global Problem
'''
import unittest

_fred = None

def start():
    global _fred
    if _fred is None:
        _fred = 39
    _fred += 3

def stop():
    global _fred
    if _fred is not None:
        del _fred

class Test(unittest.TestCase):
    def setUp(self):
        start()

    def tearDown(self):
        stop()

    def test_running_first_time(self):
        assert(_fred == 42)

    def test_running_second_time(self):
        assert(_fred == 42)

if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

実際のコードでは、_fred は Thread から派生したクラスのインスタンスを参照する変数であり (私が行ったことを参照)、start メソッドで割り当てられます。
_fred = MyThreadClass()
同期キュー用の 2 番目のグローバルがあります。
メソッドは、専用スレッドでキュー アイテムの処理を開始および停止します。'stop' は、アイテムの追加を許可しながら処理を停止します。
スレッドの API では、単一の呼び出しのみを開始できます。したがって、処理を再開するには、Thread の新しいインスタンスが必要です。したがって、の使用

if _fred is None:

del _fred

私の第一言語を推測しても賞品はありません

4

3 に答える 3

4

del _fred_fredまたはそのようなものには設定されませんNone。名前を削除します_fred。完全に。グローバルの場合、それは存在しなかったかのようです。地元の場合、割り当てられたことがないかのようです。変数を に設定するNoneには、明らかなことを行います。

_fred = None
于 2013-05-09T20:47:00.813 に答える
2

これを行う場合:

def stop():
    global _fred
    if _fred is not None:
        del _fred

実際にこのモジュールのグローバル変数ディクショナリにアクセスしており、fred が None でない場合、変数fred をモジュールから削除しています (もう存在しません)。単体テストは、各テストメソッドに対して setUp と TeaDown を呼び出します。最初のメソッドの TeaDown は、モジュール変数 dict から _fred を削除します。これにより、2 番目の setUp が失敗します。

おそらくこれはあなたがやりたいことです:

if _fred is not None:
    _fred = None

一方、新しいクラスに開始と停止を配置し、このクラスの _fred グローバル インスタンスを作成することをお勧めします。

class Fred:
    def __init__(self):
        self.state = None

    def start(self):
        if self.state is None:
            self.state = 39
        self.state += 3

    def stop(self):
        if self.state is not None:
            self.state = None

_fred = Fred()

class Test(unittest.TestCase):
    def setUp(self):
        _fred.start()

    def tearDown(self):
        _fred.stop()

    def test_running_first_time(self):
        self.assertEqual(_fred.state, 42)

    def test_running_second_time(self):
        self.assertEqual(_fred.state, 42)
于 2013-05-09T20:56:15.097 に答える
2

問題はdel _fred. インタープリター_fredがグローバルであることを伝えているため_fred、グローバル辞書から削除され、に設定されていませんNone。何かがグローバルであることを関数に伝えると、関数はそれを覚えているので、その変数名で操作を実行すると、グローバルに実行されます。 global _fredinは、が未定義であってもstartの値に影響を与えません。それは通訳者次第です。_fred_fred

于 2013-05-09T20:55:58.643 に答える