2

我想使用一个独立于类可能具有的任何对象的变量:

    class A:
        var = 5
    ob1 = A()
    ob2 = A()
    ob1.var += 2
    print ob2.var

我希望一旦 ob1 将 var 的值从 5 修改为 7,ob2.var 也会显示 7 而不是 5。我该怎么做?

4

3 回答 3

5

当您这样做时,ob1.var += 2您不是在修改类属性,而是在创建一个与类属性同名的新实例变量。例如:

>>> ob1 = A()
>>> ob1.var += 2
>>> ob1.__dict__
{'var': 7}
>>> ob1.__class__.__dict__
{'var': 5, '__module__': '__main__', '__doc__': None}

如果要修改类属性,只需使用A.var += 2. 如果您需要从实例执行此操作,您可以使用ob1.__class__.var += 2.

以下是您如何使用新样式类的属性来实现您想要的行为:

class A(object):
    _var = 5

    @property
    def var(self):
        return self.__class__._var

    @var.setter
    def var(self, value):
        self.__class__._var = value

现在有了这个类,当您var在 的实例上获取或设置变量时A,它实际上将获取或设置类属性。例如:

>>> ob1 = A()
>>> ob2 = A()
>>> ob1.var += 2
>>> ob2.var
7
于 2013-04-10T16:48:28.473 回答
2

你已经很近了

class MyData:
    my_data_var = 4

class A:
    def fun1():
       MyData.my_data_var += 2

    def fun2():
       return MyData.my_data_var

def main():
    print MyData.my_data_var 
    a = A()
    a.fun1()    
    print a.fun2()
    b = A()
    b.fun1()
    print b.fun2()
    print a.fun1()

main()

这些是静态类变量......还有其他方法可以类似地利用它们......但这是一个简单的快速示例

于 2013-04-10T16:47:28.803 回答
2

我想你可以使用 aproperty来做这样的事情:

class Foo(object):
    _var = 5

    @property
    def var(self):
        return self._var

    @var.setter
    def var(self,value):
        self.__class__._var = value

a = Foo()
b = Foo()

a.var += 3
assert a.var == 8
assert b.var == 8

c = Foo()
assert c.var == 8 #(un-instantiated objects pick up the change as well)

class Bar(Foo):
    pass

bar = Bar()
assert bar.var == 8
a.var += 1

#changes to Foo.var affect Bar until a bar object makes it's own changes
assert bar.var == 9    

# changes to a subclass's property don't have any effect on the parent class
bar.var += 2
assert bar.var == 11
assert a.var == 9

如评论中所述,如果您有很多以这种方式运行的属性,这可能会有点乏味。稍微更通用的解决方案是执行以下操作:

class ClassAttribute(object):
    def __init__(self,vname,default=None):
        self.vname = '_'+str(vname)
        self.default = default

    def __get__(self,instance,owner):
        return getattr(owner,self.vname,self.default)

    def __set__(self,instance,value):
        setattr(instance.__class__,self.vname,value)

class Foo(object):
    var = ClassAttribute("var",5)

a = Foo()
b = Foo()
a.var += 2
print a.var
print b.var
于 2013-04-10T16:54:59.030 回答