Szukaj…


Składnia

  • 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

Podstawowy dostęp do atrybutów za pomocą notacji kropkowej

Weźmy przykładową klasę.

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

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

W Pythonie można uzyskać dostęp do tytułu atrybutu klasy za pomocą notacji kropkowej.

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

Jeśli atrybut nie istnieje, Python zgłasza błąd:

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

Settery, Gettery i właściwości

Ze względu na enkapsulację danych czasami trzeba mieć atrybut, którego wartość pochodzi od innych atrybutów lub, ogólnie rzecz biorąc, którą wartość należy obecnie obliczyć. Standardowym sposobem radzenia sobie z tą sytuacją jest stworzenie metody o nazwie getter lub setter.

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

W powyższym przykładzie łatwo zobaczyć, co się stanie, jeśli utworzymy nową książkę zawierającą tytuł i autora. Jeśli wszystkie książki, które mamy dodać do naszej Biblioteki, mają autorów i tytuły, możemy pominąć metody pobierające i ustawiające oraz używać notacji kropkowej. Załóżmy jednak, że mamy książki, które nie mają autora i chcemy ustawić autora na „Nieznany”. Lub jeśli mają wielu autorów i planujemy zwrócić listę autorów.

W takim przypadku możemy utworzyć getter i setter dla atrybutu autor .

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

Ten schemat nie jest zalecany.

Jednym z powodów jest haczyk: Załóżmy, że zaprojektowaliśmy naszą klasę z publicznym atrybutem i bez metod. Ludzie już go często używali i napisali następujący kod:

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

Teraz mamy problem. Ponieważ autor nie jest atrybutem! Python oferuje rozwiązanie tego problemu zwane właściwościami. Metoda uzyskiwania właściwości jest ozdobiona @property przed jej nagłówkiem. Metoda, którą chcemy funkcjonować jako setter, jest dekorowana przed @ atrybutName.setter.

Mając to na uwadze, mamy teraz naszą nową zaktualizowaną klasę.

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

Uwaga: normalnie Python nie pozwala na posiadanie wielu metod o tej samej nazwie i różnej liczbie parametrów. Jednak w tym przypadku Python pozwala na to ze względu na zastosowane dekoratory.

Jeśli przetestujemy kod:

>>> 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow