Поиск…


Синтаксис

  • x.title # Accesses the title attribute using the dot notation
  • x.title = "Hello World" # Sets the property of the title attribute using the dot notation
  • @property # Used as a decorator before the getter method for properties
  • @title.setter # Used as a decorator before the setter method for properties

Доступ к базовому атрибуту с использованием точечной нотации

Возьмем образец класса.

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

book1 = Book(title="Right Ho, Jeeves", author="P.G. Wodehouse")

В Python вы можете получить доступ к названию атрибута класса с помощью точечной нотации.

>>> book1.title 
'P.G. Wodehouse'

Если атрибут не существует, Python выдает ошибку:

>>> book1.series
Traceback  (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Book' object has no attribute 'series'

Setters, Getters & Properties

Для инкапсуляции данных иногда вы хотите иметь атрибут, значение которого исходит от других атрибутов или, в общем, какое значение должно вычисляться в данный момент. Стандартный способ справиться с этой ситуацией - создать метод, называемый getter или setter.

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

В приведенном выше примере легко увидеть, что произойдет, если мы создадим новую книгу, содержащую название и автора. Если у всех книг, которые мы должны добавить в нашу Библиотеку, есть авторы и названия, мы можем пропустить геттеры и сеттеры и использовать точечную нотацию. Однако предположим, что у нас есть несколько книг, у которых нет автора, и мы хотим установить автора в «Неизвестный». Или, если у них есть несколько авторов, и мы планируем вернуть список авторов.

В этом случае мы можем создать getter и setter для атрибута author .

class P:
    def __init__(self,title,author):
        self.title = title
        self.setAuthor(author)

    def get_author(self):
        return self.author

    def set_author(self, author):
        if not author: 
            self.author = "Unknown"
        else:
            self.author = author

Эта схема не рекомендуется.

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

>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = ""  #Cos Some Guy didn't write this one!

Теперь у нас есть проблема. Потому что автор не является атрибутом! Python предлагает решение этой проблемы, называемой свойствами. Метод получения свойств украшен параметром @property перед его заголовком. Метод, который мы хотим использовать в качестве сеттера, украшен атрибутом @ attributeName.setter перед ним.

Помня об этом, теперь у нас есть новый обновленный класс.

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    @property
    def author(self):
        return self.__author

    @author.setter
    def author(self, author):
        if not author: 
            self.author = "Unknown"
        else:
            self.author = author

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

Если мы проверим код:

>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = ""  #Cos Some Guy didn't write this one!
>>> book.author 
Unknown 


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow