Переменные экземпляра по сравнению с переменными класса в Python

У меня есть классы Python, из которых мне нужен только один экземпляр во времени выполнения, таким образом, было бы достаточно иметь атрибуты только однажды в классе а не в экземпляре. Если был бы больше чем один экземпляр (которого не произойдет), весь экземпляр должен иметь ту же конфигурацию. Интересно, какая из следующих опций была бы лучше или больше "идиоматического" Python.

Переменные класса:

class MyController(Controller):

  path = "something/"
  children = [AController, BController]

  def action(self, request):
    pass

Переменные экземпляра:

class MyController(Controller):

  def __init__(self):
    self.path = "something/"
    self.children = [AController, BController]

  def action(self, request):
    pass
115
задан ndmeiri 18 February 2017 в 03:37
поделиться

3 ответа

Если в любом случае у вас есть только один экземпляр, лучше всего сделать все переменные для каждого экземпляра просто потому, что к ним будет доступ (немного) быстрее (один меньший уровень «поиска» из-за «наследования» от класса к экземпляру), и нет никаких недостатков, которые можно было бы сопоставить с этим небольшим преимуществом.

150
ответ дан 24 November 2019 в 02:25
поделиться

повторяя совет Майка и Алекса и добавляя свой собственный цвет ...

с использованием атрибутов экземпляра - это типичный, более идиоматичный Python. Атрибуты класса не часто используются - по крайней мере, в производственном коде за последние 13 с лишним лет подряд Python. то же самое верно для статических методов и методов класса ... просто не очень распространено, если нет конкретного варианта использования или отклоняющегося программиста, желающего показать, что он знает какой-то неясный уголок программирования Python.

alex упоминает в своем ответе, что доступ будет (немного) быстрее из-за на один уровень поиска меньше ... позвольте мне пояснить для тех, кто еще не знает, как это работает, это очень похоже на доступ к переменным - поиск происходит в следующем порядке:

  1. locals
  2. nonlocals
  3. globals
  4. встроенные функции

для доступа к атрибутам, порядок следующий:

  1. instance
  2. class
  3. , как определено MRO (порядок разрешения методов)

в приведенном выше примере, допустим, вы ищете атрибут path . когда он встречает ссылку типа « self.path », Python сначала проверяет атрибуты экземпляра на соответствие; когда это не удается, он проверяет класс, из которого был создан объект. наконец, он будет искать базовые классы.как заявил Алекс, если ваш атрибут найден в экземпляре, он не будет относиться к классу, следовательно, вы сэкономите немного времени.

однако, если вы настаиваете на атрибутах класса, вам придется отказаться от этой крошечной части производительности, или , другой альтернативой является обращение к объекту через класс вместо экземпляра, например , MyController.path вместо self.path . это прямой поиск, который будет обходить отложенный поиск, но, как упоминает Алекс ниже, это глобальная переменная, поэтому вы теряете тот бит, который, как вы думали, собирались сохранить (если вы не создадите локальную ссылку на имя [global] класса ).

42
ответ дан 24 November 2019 в 02:25
поделиться

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

Атрибуты класса лучше всего зарезервировать для особых случаев, когда они имеют смысл. Единственный очень распространенный вариант использования - это методы. Нередко использование атрибутов класса для констант, доступных только для чтения, которые должны знать экземпляры (хотя единственное преимущество в том, что вы также хотите получить доступ из вне класса), но вы, конечно, должны быть осторожны с хранением в них любого состояния, что редко бывает тем, что вам нужно. Даже если у вас будет только один экземпляр, вы должны написать класс так же, как и любой другой, что обычно означает использование атрибутов экземпляра.

24
ответ дан 24 November 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: