Python模块/类可变出血

Ian*_*Ian 0 python oop class

好吧,我花了一点时间来缩小这个问题,但看来python正在做这个目的.有人可以解释为什么会发生这种情况以及我可以做些什么来解决这个问题?

文件:library/testModule.py

class testClass:

    myvars = dict()

    def __getattr__(self, k):
        if self.myvars.has_key(k):
            return self.myvars[k]

    def __setattr__(self, k, v):
        self.myvars[k] = v

    def __str__(self):
        l = []
        for k, v in self.myvars.iteritems():
            l.append(str(k) + ":" + str(v))

        return " - ".join(l)
Run Code Online (Sandbox Code Playgroud)

test.py

from library import testModule

#I get the same result if I instantiate both classes one after another
c1 = testClass()
c1.foo = "hello"
c2 = testClass()

print("c1: " + str(c1) + "\n")
print("c2: " + str(c2) + "\n")
Run Code Online (Sandbox Code Playgroud)

输出:

c1: foo:hello
c2: foo:hello
Run Code Online (Sandbox Code Playgroud)

我最好的猜测是,因为library有一个"__init__.py"文件,整个模块就像一个类对象一样加载,它现在成为持久对象的一部分..这是这种情况吗?

Dav*_*d Z 7

myvars的属性,而不是实例.这意味着当您myvars从实例插入属性时c1,该属性将与该类关联testClass,而不是与该实例c1特定关联.由于c2是同一个类的实例,因此它也具有相同的属性.

您可以通过编写以下内容来获得所需的行为:

class testClass:
    def __init__(self):
        self.myvars = dict()

    def __getattr__(self, k):
        if self.myvars.has_key(k):
            return self.myvars[k]

    def __setattr__(self, k, v):
        self.myvars[k] = v

    def __str__(self):
        l = []
        for k, v in self.myvars.iteritems():
            l.append(str(k) + ":" + str(v))
        return " - ".join(l)
Run Code Online (Sandbox Code Playgroud)