Почему свойства должны быть атрибутами класса в Python?

Недавно я узнал об управляемых атрибутах в Python, а общая тема со свойствами и дескрипторами заключается в том, что они должны быть назначены как атрибуты класса. Но нигде я не могу найти объяснения, почему и особенно почему они не могут быть назначены как атрибуты экземпляра. Таким образом, мой вопрос состоит из двух частей:

  • почему экземпляры свойств / дескрипторов должны быть атрибутами класса?
  • почему экземпляры свойств / дескрипторов не являются атрибутами экземпляра?

2 Solutions collect form web for “Почему свойства должны быть атрибутами класса в Python?”

Это связано с тем, как Python пытается разрешить атрибуты:

  1. Сначала он проверяет, определено ли это на уровне класса
  2. Если да, то он проверяет, является ли это свойством или дескриптором данных
  3. Если да, то следует этот «путь»,
  4. Если нет, он проверяет, является ли это простой переменной класса (до ее родительских классов, если таковые имеются)
  5. Если да, он проверяет, что экземпляр переопределяет это значение атрибута класса, если да, он возвращает значение переопределения, если оно не возвращает значение атрибута класса
  6. Если нет, он проверяет, объявляет ли этот атрибут этот атрибут
  7. Если да, он возвращает значение атрибута экземпляра
  8. Если нет, он выбрасывает AttributeError

Voila 😉

РЕДАКТИРОВАТЬ

Я просто нашел эту ссылку, которая объясняет это лучше меня.

Еще одна хорошая иллюстрация .

почему экземпляры свойств / дескрипторов должны быть атрибутами класса?

Им не обязательно быть, они просто есть. Это было дизайнерское решение, у которого, вероятно, есть еще много причин для его резервного копирования, чем я могу думать (упрощая реализацию, отделяя классы от объектов).

почему экземпляры свойств / дескрипторов не являются атрибутами экземпляра?

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

Имейте в виду, что тот факт, что Python не остановит вас от этого, не означает, что это хорошая идея.

  • TypeError: worker () принимает 0 позиционных аргументов, но 1 дано
  • Python 3.5.1 urllib не имеет запроса атрибута
  • Django Rest Framework - нет модуля с именем rest_framework
  • Конструкция объекта Python 3: что является наиболее Pythonic / принято?
  • Преобразуйте набор чисел в numpy, чтобы каждый номер преобразовывался в ряд других чисел, которые меньше, чем это
  • Python объединяет элементы списка сложным способом
  • Как заставить весь пакет использовать директиву __future__?
  • Как запустить код генератора параллельно?
  • Python - лучший язык программирования в мире.