Reputation: 4237
I want to use a variable that will be independent of any objects the class may have :
class A:
var = 5
ob1 = A()
ob2 = A()
ob1.var += 2
print ob2.var
I want that once ob1 modifies the value of var from 5 to 7, ob2.var also shows up 7 instead of 5. How do I do this?
Upvotes: 2
Views: 116
Reputation: 310227
I suppose you could use a property
to do something like this:
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
As noted in the comments, this could get a little tedious if you have a lot of properties which behave this way. A slightly more general solution would be to do something like:
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
Upvotes: 2
Reputation: 208665
When you do ob1.var += 2
you are not modifying the class attribute, you are creating a new instance variable with the same name as the class attribute. For example:
>>> ob1 = A()
>>> ob1.var += 2
>>> ob1.__dict__
{'var': 7}
>>> ob1.__class__.__dict__
{'var': 5, '__module__': '__main__', '__doc__': None}
If you want to modify the class attribute, just use A.var += 2
. If you need to do this from an instance you can use ob1.__class__.var += 2
.
Here is how you could implement the behavior you want using properties on a 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
Now with this class when you get or set the var
variable on an instance of A
, it will actually be getting or setting a class attribute. For example:
>>> ob1 = A()
>>> ob2 = A()
>>> ob1.var += 2
>>> ob2.var
7
Upvotes: 5
Reputation: 114088
you are already close
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()
these are static class variables ... there are other ways to simillarly utilize them ... but this was a simple quick example
Upvotes: 2