Changing variables in multiple Python instances

后端 未结 4 430
感情败类
感情败类 2021-01-18 22:24

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         


        
相关标签:
4条回答
  • 2021-01-18 22:31

    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)
    
    0 讨论(0)
  • 2021-01-18 22:37

    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.

    0 讨论(0)
  • 2021-01-18 22:48

    "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
    
    0 讨论(0)
  • 2021-01-18 22:55

    What about using a class attribute?

    class Object():
        speed=0
    
    instance0=Object()
    instance1=Object()
    instance2=Object()
    
    Object.speed=5
    
    0 讨论(0)
提交回复
热议问题