在多个Python实例中更改变量

在多个Python实例中更改变量,python,class,object,Python,Class,Object,是否可以同时设置类的所有实例的变量?我有一个简化的例子如下: class Object(): def __init__(self): self.speed=0 instance0=Object() instance1=Object() instance2=Object() #Object.speed=5 doesn't work of course 我可以看到,将所有新实例添加到列表并使用isinstance()进行迭代是可能的,但这并不可取。使用class属性怎么样

是否可以同时设置类的所有实例的变量?我有一个简化的例子如下:

class Object():
   def __init__(self):
       self.speed=0

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

#Object.speed=5 doesn't work of course

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

使用class属性怎么样

class Object():
    speed=0

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

Object.speed=5

可以使用类属性:

class Object():
   speed = 0 

instance0=Object()
instance1=Object()
instance2=Object()
Object.speed=5
# instance0.speed == instance1.speed == instance2.speed == Object.speed == 5
>>> 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
但是,这意味着所有实例将始终具有相同的
速度

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

这是一个类属性

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

class Object():
   speed = 0 

instance0=Object()
instance1=Object()
instance2=Object()
Object.speed=5
# instance0.speed == instance1.speed == instance2.speed == Object.speed == 5
>>> 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

另一个答案指出,一个更简单的方法是将属性始终保持为类属性。如果在类主体上设置了该属性,并且对该属性的所有写访问都是通过类名而不是通过实例进行的,则可以:

>>> class Object(object):
...     speed = 0
... 
>>> a = Object()
>>> b = Object()
>>> c = Object()
>>> 
>>> Object.speed = 5
>>> print a.speed
5
>>> 
但是,如果以这种方式在单个实例中设置属性,则该实例将具有自己的属性,并且不再随其他实例的属性一起更改:

>>> a.speed = 10
>>> Object.speed = 20
>>> print b.speed
20
>>> print a.speed
10
>>>
要克服这一点,以便无论何时在任何实例中设置属性,都会更改类属性本身,更简单的方法是将对象作为属性—其setter设置类属性:

class Object(object):
  _speed = 0
  @property
  def speed(self):
     return self.__class__._speed
  @speed.setter
  def speed(self, value):
     self.__class__._speed = value
有效的方法是:

>>> 
>>> a = Object()
>>> b = Object()
>>> a.speed, b.speed
(0, 0)
>>> a.speed = 10
>>> a.speed, b.speed
(10, 10)
如果您希望实例上有独立的属性,但有一个特殊的“set_all”方法可以在所有实例中设置属性,那么方法是使用标准librayr中的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
其结果是:

>>> 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)