13

Python クラス オブジェクトがあり、1 つのクラス変数の値を割り当てたい

class Groupclass(Workerclass):
    """worker class"""
    count = 0

    def __init__(self):
        """initialize time"""
        Groupclass.count += 1
        self.membercount = 0;
        self.members = []

    def __del__(self):
        """delte a worker data"""
        Groupclass.count -= 1


if __name__ == "__main__":
    group1 = Groupclass()

この実行結果は正しいですが、次のようなエラー メッセージが表示されます。

Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored

誰かが私が間違っていたことを教えてもらえますか?

4

2 に答える 2

17

メソッド__del__は、呼び出されるまでにクラスがまだ存在していることを前提としています。

この仮定は正しくありません。Groupclassは、Python プログラムが終了した時点で既にクリアされており、現在は に設定されていNoneます。

クラスへのグローバル参照がまだ存在するかどうかを最初にテストします。

def __del__(self):
    if Groupclass:
        Groupclass.count -= 1

またはtype()ローカル参照を取得するために使用します。

def __del__(self):
    type(self).count -= 1

ただし、これはcount変更のセマンティクスGroupclassがサブクラス化されていることを意味することに注意してください (各サブクラスは.count属性を取得するのではなく、属性のみGroupclassを取得し.countます)。

__del__フックのドキュメントからの引用:

警告: メソッドが呼び出される不安定な状況のため__del__()、実行中に発生する例外は無視され、sys.stderr代わりに警告が出力されます。また、__del__()モジュールの削除に応答して が呼び出された場合 (たとえば、プログラムの実行が完了したとき)、__del__()メソッドによって参照されている他のグローバルが既に削除されているか、取り壊されている途中である可能性があります (インポート機構のシャットダウンなど)。 )。このために、__del__()メソッドは、外部不変条件を維持するために必要な絶対最小値を実行する必要があります。バージョン 1.5 以降、Python は、名前が単一のアンダースコアで始まるグローバルが、他のグローバルが削除される前にモジュールから削除されることを保証します。__del__()そのようなグローバルへの他の参照が存在しない場合、これは、メソッドが呼び出されたときにインポートされたモジュールがまだ使用可能であることを保証するのに役立ちます。

Python 3 を使用している場合は、2 つの追加の注意事項が適用されます。

  • CPython 3.3は、辞書で使用されるキーにランダム化されたハッシュ ソルトを自動的に適用します。これは、グローバルがクリーンアップされる順序にも影響し、一部の実行でのみ問題が発生する可能性があります。strglobals

  • Safe Object FinalizationNoneに従って、CPython 3.4 はグローバルを (ほとんどの場合) に設定しなくなりました。PEP 442を参照してください。

于 2013-08-05T13:02:27.713 に答える