Изменение переменных в нескольких экземплярах Python - PullRequest
4 голосов
/ 16 февраля 2012

Есть ли способ установить переменные всех экземпляров класса одновременно? У меня есть упрощенный пример ниже:

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

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

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

Я вижу, что это было бы возможно, добавив все новые экземпляры в список и повторив isinstance (), но это нежелательно.

Ответы [ 4 ]

18 голосов
/ 16 февраля 2012

Один, более простой способ, как говорят другие ответы, заключается в том, чтобы ваш атрибут всегда оставался атрибутом класса.Если он установлен в теле класса, и все права на запись для атрибута осуществляются через имя класса, а не экземпляр, это будет работать:

>>> 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) в стандартном librayr, чтобы найти и просмотреть все экземплярыкласс, и установите их атрибуты экземпляра:

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 голосов
/ 16 февраля 2012

Вы можете использовать атрибут класса:

class Object():
   speed = 0 

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

Однако это будет означать, что все экземпляры всегда будут иметь одинаковые speed.

2 голосов
/ 16 февраля 2012

А как насчет использования атрибута класса?

class Object():
    speed=0

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

Object.speed=5
0 голосов
/ 16 февраля 2012

"Есть ли способ установить переменные всех экземпляров класса одновременно ?"

Это атрибут класса!

Некоторые примеры доступа к атрибуту класса:

>>> 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...