我想使用一个独立于类可能具有的任何对象的变量:
class A:
var = 5
ob1 = A()
ob2 = A()
ob1.var += 2
print ob2.var
我希望一旦ob1将var的值从5修改为7,ob2.var也会显示7而不是5.我该怎么做?
答案 0 :(得分:5)
执行ob1.var += 2
时,您没有修改类属性,而是创建一个与class属性同名的新实例变量。例如:
>>> 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
。
以下是使用new-style class上的属性实现所需行为的方法:
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
答案 1 :(得分: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()
这些是静态类变量......还有其他方法可以模拟地使用它们......但这只是一个简单的快速示例
答案 2 :(得分:2)
我想你可以用property
来做这样的事情:
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