Is there anyway to set the variables of all instances of a class at the same time? I've got a simplified example below:
class Object():
def __init__(self):
self.speed=0
instance0=Object()
instance1=Object()
instance2=Object()
#Object.speed=5 doesn't work of course
I can see it would be possible by adding all new instances to a list and iterating with isinstance(), but that's not desirable.
We can modify the value of the instance variable and assign a new value to it using the object reference. Note: When you change the instance variable's values of one object, the changes will not be reflected in the remaining objects because every object maintains a separate copy of the instance variable.
Python assigns values from right to left. When assigning multiple variables in a single line, different variable names are provided to the left of the assignment operator separated by a comma. The same goes for their respective values except they should be to the right of the assignment operator.
You already know that every object of that type can have different instance variable values.
The assignment operator, denoted by the “=” symbol, is the operator that is used to assign values to variables in Python. The line x=1 takes the known value, 1, and assigns that value to the variable with name “x”. After executing this line, this number will be stored into this variable.
One, simpler way, as the other answers put it, is to keep your attribute always as a class attribute. If it is set on the class body, and all write access to the attribute is via the class name, not an instance, that would work:
>>> class Object(object):
... speed = 0
...
>>> a = Object()
>>> b = Object()
>>> c = Object()
>>>
>>> Object.speed = 5
>>> print a.speed
5
>>>
However, if you ever set the attribute in a single instance doing it this way, the instance will have its own attribute and it will no longer change along with the other instance's:
>>> a.speed = 10
>>> Object.speed = 20
>>> print b.speed
20
>>> print a.speed
10
>>>
To overcome that, so that whenever the attribute is set in any instance, the class attribute itself is changed, the easier way is to have the object as a property - whose setter sets the class attribute instead:
class Object(object):
_speed = 0
@property
def speed(self):
return self.__class__._speed
@speed.setter
def speed(self, value):
self.__class__._speed = value
Which works:
>>>
>>> a = Object()
>>> b = Object()
>>> a.speed, b.speed
(0, 0)
>>> a.speed = 10
>>> a.speed, b.speed
(10, 10)
If you want to have independent attribute on the instances, but a special "set_all" method that would set the attribute in all instances, the way to go is to use the gc (Garbage Collector) module in standard librayr, to find and loop through all instances of the class, and set their instance attributes:
import gc
class Object(object):
def __init__(self):
self.speed = 0
def set_all_speed(self, value):
for instance in (obj for obj in gc.get_referrers(self.__class__):
if isinstance(obj, self.__class__)):
instance.speed = value
Which results in:
>>> a =Object()
>>> b = Object()
>>> a.speed = 5
>>> b.speed = 10
>>> a.speed, b.speed
(5, 10)
>>> a.set_all_speed(20)
>>> a.speed, b.speed
(20, 20)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With