Python Language
Dostęp do atrybutów
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