在多个Python实例中更改变量

时间:2022-01-14 17:04:25

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.

我可以看到将所有新实例添加到列表并使用isinstance()进行迭代是可能的,但这是不可取的。

4 个解决方案

#1


16  

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:

为了克服这个问题,每当在任何实例中设置属性时,类属性本身都会被更改,更简单的方法是将对象作为属性 - 其setter设置class属性:

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:

如果你想在实例上有独立的属性,但是一个特殊的“set_all”方法可以在所有实例中设置属性,那么可以使用标准库中的gc(垃圾收集器)模块来查找和循环该类的所有实例,并设置其实例属性:

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)

#2


2  

What about using a class attribute?

那么使用class属性呢?

class Object():
    speed=0

instance0=Object()
instance1=Object()
instance2=Object()

Object.speed=5

#3


2  

You could use a class attribute:

您可以使用类属性:

class Object():
   speed = 0 

instance0=Object()
instance1=Object()
instance2=Object()
Object.speed=5
# instance0.speed == instance1.speed == instance2.speed == Object.speed == 5

However this would mean that all instances would always have the same speed.

但是,这意味着所有实例总是具有相同的速度。

#4


0  

"Is there any way to set the variables of all instances of a class at the same time?"

“有没有办法同时设置类的所有实例的变量?”

That's a class attribute!

这是一个类属性!

Some examples on how to access a class attribute:

有关如何访问类属性的一些示例:

>>> class Object:
...     speed = 5
...     @classmethod
...     def first(cls):
...         return cls.speed
...     def second(self):
...         return self.speed
...
>>> Object.speed
5 
>>> instance = Object()
>>> instance.speed
5
>>> instance.first()
5
>>> instance.second()
5

#1


16  

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:

为了克服这个问题,每当在任何实例中设置属性时,类属性本身都会被更改,更简单的方法是将对象作为属性 - 其setter设置class属性:

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:

如果你想在实例上有独立的属性,但是一个特殊的“set_all”方法可以在所有实例中设置属性,那么可以使用标准库中的gc(垃圾收集器)模块来查找和循环该类的所有实例,并设置其实例属性:

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)

#2


2  

What about using a class attribute?

那么使用class属性呢?

class Object():
    speed=0

instance0=Object()
instance1=Object()
instance2=Object()

Object.speed=5

#3


2  

You could use a class attribute:

您可以使用类属性:

class Object():
   speed = 0 

instance0=Object()
instance1=Object()
instance2=Object()
Object.speed=5
# instance0.speed == instance1.speed == instance2.speed == Object.speed == 5

However this would mean that all instances would always have the same speed.

但是,这意味着所有实例总是具有相同的速度。

#4


0  

"Is there any way to set the variables of all instances of a class at the same time?"

“有没有办法同时设置类的所有实例的变量?”

That's a class attribute!

这是一个类属性!

Some examples on how to access a class attribute:

有关如何访问类属性的一些示例:

>>> class Object:
...     speed = 5
...     @classmethod
...     def first(cls):
...         return cls.speed
...     def second(self):
...         return self.speed
...
>>> Object.speed
5 
>>> instance = Object()
>>> instance.speed
5
>>> instance.first()
5
>>> instance.second()
5