Когда использовать «свойство» builtin: вспомогательные функции и генераторы

Недавно я обнаружил встроенное property Python, которое маскирует метод getter и seters класса как свойство класса. У меня теперь возникает соблазн использовать его так, что я уверен, что это неуместно.

Правильно использовать ключевое слово property , если класс A имеет свойство _x , допустимые значения которого вы хотите ограничить; т.е. он заменит конструкцию getX() и setX() можно написать в C ++.

Но где еще уместно сделать функцию свойством? Например, если у вас есть

 class Vertex(object): def __init__(self): self.x = 0.0 self.y = 1.0 class Polygon(object): def __init__(self, list_of_vertices): self.vertices = list_of_vertices def get_vertex_positions(self): return zip( *( (vx,vy) for v in self.vertices ) ) 

целесообразно добавить

  vertex_positions = property( get_vertex_positions ) 

?

Всегда ли, чтобы генератор выглядел как собственность? Представьте себе, если изменение нашего кода означало, что мы больше не сохраняем Polygon.vertices одинаково. Было бы хорошо добавить это в Polygon ?

  @property def vertices(self): for v in self._new_v_thing: yield v.calculate_equivalent_vertex() 

2 Solutions collect form web for “Когда использовать «свойство» builtin: вспомогательные функции и генераторы”

  • Когда у вас есть нормальный атрибут и получение и / или настройка, это имеет смысл для пользователя класса, выставляйте атрибут напрямую. Одна из главных причин, по которым публичные участники являются анафемой на некоторых языках, заключается в том, что если вам нужно будет сделать что-то более сложное позже, вам потребуется изменение API; в Python вы можете просто определить свойство.

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

  • Если что-то не является атрибутом-y, не делайте его собственностью. Нет никакого вреда в создании метода, и это может быть выгодно: то, что он делает, более очевидно, вы можете передать некоторый связанный метод, если вам нужно, вы можете добавить аргументы ключевого слова без изменения API.

    Трудно представить себе ситуацию, когда я бы использовал функцию генератора в качестве свойства. Единственный способ иметь нормальный атрибут, который будет вести себя одинаково, потребует довольно много сложностей, поэтому этот случай не очень напоминает доступ к атрибутам.

  • Вы указываете, что вы можете использовать property для ограничения доступа к некоторому внутреннему атрибуту _x . Это может быть правдой, но имейте в виду

    • Если вы собираетесь делать такие вещи, как дезинфекция ввода для безопасности или что-то важное, явное лучше, чем неявное . Вы не хотите чувствовать, что код просто работает, когда дело доходит до таких вещей, потому что тогда вы столкнетесь с кодом, который этого не делает.

    • Иногда люди используют property для реализации атрибутов только для чтения. Обычно лучше просто иметь нормальный атрибут и понимать, что вы не можете помешать пользователю делать что-то немое и неподдерживаемое.

  • Nitpicking вам может показаться интересным:

    • property не является ключевым словом; это нормальное имя, которое вы можете восстановить. Это интересно, поскольку property не является синтаксической вещью или чем-то еще: это обычный класс, который вы могли бы реализовать в чистом Python. Он использует тот же механизм, который позволяет методам работать в Python- дескрипторах .

    • Вы описываете, что property делает как «маскирует метод getter и seters класса», что не совсем так. То, что property принимает, – это просто нормальные функции и вообще не нужно определять в вашем классе; property передаст вам. Функции фактически не становятся методами, пока вы их не просмотрите, когда Python создает объекты метода «на лету». Во время определения класса они являются просто функциями. Когда у вас нормальный метод, он называется «методом экземпляра»; в методе класса Python относится к другим специальным типам вроде подобных свойств, которые изменяют то, что происходит при поиске атрибута.

Существует очевидное ограничение в использовании свойств: оно не принимает никаких аргументов , и этого никогда не будет.

Поэтому вы должны быть уверены, что функция, которую вы трансформируете в свойство, никогда не будет реорганизована в функцию с, например, дополнительными аргументами по умолчанию.

  • Как назначить свойство экземпляру в Python?
  • Константные переменные экземпляра?
  • Использовать свойство / атрибут базового класса в качестве столбца таблицы?
  • В Python, что является предпочтительным соглашением об именах для резервного хранилища внутреннего свойства?
  • Python: как передать более одного аргумента в свойство getter?
  • SQLAlchemy - способ сопоставления с единственным (или рассчитанным) свойством
  • Измените параметр свойства внутри класса конструктора
  • Как реализовать __iadd__ для свойства Python
  • Python - лучший язык программирования в мире.