在多个Python实例中更改变量

Ubu*_*Tom 4 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
Run Code Online (Sandbox Code Playgroud)

我可以通过将所有新实例添加到列表并使用isinstance()进行迭代来实现,但这是不可取的.

jsb*_*eno 18

正如其他答案所说的那样,一种更简单的方法是将属性始终保持为类属性.如果它在类体上设置,并且对该属性的所有写访问都是通过类名而不是实例来实现的:

>>> class Object(object):
...     speed = 0
... 
>>> a = Object()
>>> b = Object()
>>> c = Object()
>>> 
>>> Object.speed = 5
>>> print a.speed
5
>>> 
Run Code Online (Sandbox Code Playgroud)

但是,如果您在单个实例中以这种方式设置属性,则实例将具有自己的属性,并且它将不再与其他实例一起更改:

>>> a.speed = 10
>>> Object.speed = 20
>>> print b.speed
20
>>> print a.speed
10
>>>
Run Code Online (Sandbox Code Playgroud)

为了克服这个问题,每当在任何实例中设置属性时,类属性本身都会被更改,更简单的方法是将对象作为属性 - 其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
Run Code Online (Sandbox Code Playgroud)

哪个有效:

>>> 
>>> a = Object()
>>> b = Object()
>>> a.speed, b.speed
(0, 0)
>>> a.speed = 10
>>> a.speed, b.speed
(10, 10)
Run Code Online (Sandbox Code Playgroud)

如果你想在实例上有独立的属性,但是一个特殊的"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
Run Code Online (Sandbox Code Playgroud)

结果如下:

>>> 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)
Run Code Online (Sandbox Code Playgroud)