【问题标题】:Changing variables in multiple Python instances在多个 Python 实例中更改变量
【发布时间】:2012-02-15 22:56:12
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: python class object


    【解决方案1】:

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

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

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

    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”方法会在所有实例中设置属性,那么可以使用标准库中的 gc (Garbage Collector) 模块,找到并遍历类的所有实例,并设置它们的实例属性:

    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)
    

    【讨论】:

      【解决方案2】:

      使用类属性怎么样?

      class Object():
          speed=0
      
      instance0=Object()
      instance1=Object()
      instance2=Object()
      
      Object.speed=5
      

      【讨论】:

        【解决方案3】:

        你可以使用类属性:

        class Object():
           speed = 0 
        
        instance0=Object()
        instance1=Object()
        instance2=Object()
        Object.speed=5
        # instance0.speed == instance1.speed == instance2.speed == Object.speed == 5
        

        但这意味着所有实例将始终具有相同的speed

        【讨论】:

          【解决方案4】:

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

          这是一个类属性!

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-08
            • 1970-01-01
            • 2018-04-16
            • 2020-08-24
            • 2017-09-10
            相关资源
            最近更新 更多