5

基本クラスで定義され、派生クラスからアクセスされる辞書が、明らかに 1 つのメモリ ロケーションにしか存在しないのはなぜだろうか。簡単な例:

class BaseClass:
    _testdict = dict()
    _testint = 0

    def add_dict_entry(self):
        self._testdict["first"] = 1

    def increment(self):
        self._testint += 1

class Class1(BaseClass):
    pass

class Class2(BaseClass):
    pass

object1 = Class1()
object2 = Class2()

object1.add_dict_entry()
object1.increment()
print(object2._testdict)
print(object2._testint)

出力は次のとおりです。

{'first': 1}
0

object1 の「add_dict_entry」への呼び出しが object2 の辞書に影響するのはなぜですか? 整数 (「インクリメント」) を使用すると、基本クラスの変数は影響を受けません。

どうもありがとう。

ローレンツ

4

2 に答える 2

10

はクラス変数であるため_testdictです。クラスが最初に構築されるときに一度だけ定義されます。インスタンスごとに分けたい場合は、インスタンス変数にします。

class BaseClass:
    _testint = 0

    def __init__(self):
        self._testdict = dict()

    def add_dict_entry(self):
        self._testdict["first"] = 1

(と__init__のメソッドを作成する必要があることに注意してください。どちらも を呼び出す必要があります)。Class1Class2BaseClass.__init__(self)

_testint変更操作ではなく再バインド操作を実行しているため、動作が異なります。int は不変であるため、1 つを「変更」することはできませself._testint += 1self._testint = self._testint + 1self._testdict同様に、インスタンス間で共有されない再バインド操作を実行できますself._testdict = {}たとえば、そのインスタンスの._testdict

于 2012-08-24T14:57:07.837 に答える
2

Pythonでは、intは不変であるため、+=操作はクラス変数をインスタンス変数にリバウンドします。一方、辞書の索引付けは、その場で辞書を変更します。より類似した例は

def add_dict_entry(self):
    # create a new dict
    tmp = dict(self._testdict)
    tmp["first"] = 1

    # shadow the class variable with an instance variables
    self._testdict = tmp
于 2012-08-24T15:04:44.267 に答える