Документация по Python

Доступ к атрибутам класса

В: Документация по Python

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

Давайте возьмем образец класса.

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' 

Сеттеры, геттеры и свойства

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

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

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

В этом случае мы можем создать геттер и сеттер для атрибута 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  

Еще от кодкамп
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.