4

I am rediscovering OOP through a GUI application I am writing and would like to understand if it is possible to change a characteristic of all objects instantiated from a class. I have the following code:

class myclass():
    def __init__(self):
        self.a = 1

x = myclass()
y = myclass()
print x.a, y.a  # outputs 1 1
# the instruction I am looking for, assigns 2 to a in each object at once
print x.a, y.a  # outputs 2 2

What I am looking for is a way to change x and y at once by manipulating the parent class. I know that I can have a method which modifies self.a - I do not want to use that because it means I have to call it separately for each object.

My gut feeling is that this is not possible and that I have to cleverly handle my objects to simplify such activities (for instance by storing them in a list I would loop over, applying a method). I just do not want to miss a mechanism which I am not aware of and which would greatly simplify my code.

WoJ
  • 27,165
  • 48
  • 180
  • 345
  • 2
    Wouldn't that be a situation where you'd use class variables instead of instance variables? – Tim Pietzcker Jul 18 '14 at 07:22
  • 1
    possible duplicate of [Static class variables in Python](http://stackoverflow.com/questions/68645/static-class-variables-in-python) – dammkewl Jul 18 '14 at 07:23

3 Answers3

9

You can have all instances share a variable if you define it as a class variable:

>>> class myclass():
...     a = 1
...     def __init__(self):
...         self.b = 2
...
>>> x = myclass()
>>> y = myclass()
>>> x.a
1
>>> myclass.a = 2   # modify the class variable
>>> x.a
2
>>> y.a
2
>>> x.b = 3         # modify the instance variable
>>> x.b
3
>>> y.b
2
>>> x.a = 4         # create new local instance variable a
>>> x.a
4
>>> y.a
2

Note that now if you change myclass.a, you won't see the change in x because the instance variable will be looked up before the class variable - until you remove the instance variable using del:

>>> myclass.a = 3
>>> x.a
4
>>> y.a
3
>>> del x.a
>>> x.a
3
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
3

No, you can't. Object data can't be changed without pointer to the object. Possibly you need class variables and classmethod:

class myclass:
  a = 1
  @classmethod
  def set_a(cls, val):
    cls.a = val

x = myclass()
y = myclass()
print x.a, y.a  # outputs 1 1
myclass.set_a(2)
print x.a, y.a  # outputs 2 2

But in such case you cant change a value of objects separately. If you want such behavior you can save all instances of objects in classdata such follows:

class myclass:

  objects = []

  def __init__(self):
    self.a = 1
    # add instantiated object to object list 
    self.__class__.objects.append(self)

  @classmethod
  def set_all(cls, val):
    # go through list and change each object
    for obj in cls.objects:
      obj.a = 2

x = myclass()
y = myclass()
print x.a, y.a  # outputs 1 1
myclass.set_all(2)
print x.a, y.a  # outputs 2 2
# and you cat change data of each object separately:
x.a = 3
print x.a, y.a  # outputs 3 2
RomanHotsiy
  • 4,978
  • 1
  • 25
  • 36
0
class myclass():
    a=10
    def __init__(self):
        self.b=0

a=myclass()
b=myclass()
print a.a,b.a #output 10,10
myclass.a=2
a=myclass()
b=myclass()


print a.a,b.a #output 2,2
sundar nataraj
  • 8,524
  • 2
  • 34
  • 46