Możecie mi objaśnić kiedy w jakim wypadku można tworzyć zmienną jako prywatną przykładowo ( __stan = 20) w klasie przykładowego konta bankowego . I czy te zmienne prywatne stosujemy wraz z dekoratorem @property
zawsze? Dążę do zrozumienia tych "zawiłości" w klasach w pythonie.
Zacznę od końca, czym jest @property
- to dekorator który pozwala nadać klasie interfejs atrybutu, nawet jeśli ten atrybut nie istnieje:
Kopiuj
class Test:
@property
def test():
return 'nieistniejące pole'
t = Test()
test.test;
Z takiego "property" oczywiście możemy zwrócić co nam się tylko podoba: stałą wartość, wartość kalkulowaną z czegoś (np długość listy jednokierunkowej), wartość cache'owaną, lub cokolwiek innego. Takie property nie specjalnie różni się czymkolwiek od zwykłej funkcji bez argumentowej, poza składnią (test.test
, zamiat test.test()
,). Dodatkowo, zmiana wartości takie property jest niedozwolona (nie można zrobić test.test = "new value"
, tak jak dałoby się z polem), chyba że użyje się @property.setter
, ale znowu, nie różni się to specjalnie niczym od funkcji (oprócz zapisem, czyli test.test = "new value"
zamiast test.setTest("new value")
). Niektórzy mogą uznać zapis z @property
za bardziej elegancki i prostszy - z czym się zgadzam, ale samym w sobie to żadnym nie wiadomo czym nie jest.
No więc nie chodzi o żadne "bezpieczeństwo" czy "dostęp" do pól instancji, tylko chodzi tylko i wyłącznie o to czy chcesz żeby dane pole było częścią interfejsu Twojej klasy czy nie. Innymi słowy, czy jeśli wprowadzisz zmianę w tej zmiennej, to czy chcesz zmieniać inne miejsca w kodzie gdzie jest używana, czy tylko wewnątrz klasy. Jeśli tak, to zrób zwykłe pole pythonowe, tzw. instance field. Jeśli nie, to (akurat w pythonie) nie specjalnie możesz cokolwiek z tym zrobić, oprócz nazwania tego pola z podkreślnikami _field
lub __field
, żeby dać znać użytkownikowi klasy (czyli w 99% samemu sobie), że lepiej tego pola nie ruszać (bo może być stanowe, zawierać szczegóły implementacyjne, zmieniać się w przyszłości, etc.). Jeśli masz dodać jakieś pole, to dobrze jest od kopa ustawić je jako prywatne, jeśli nie używasz go nigdzie.
Teraz co jeśli chcemy jednak skorzystać z takiego pola w innych klasach, wtedy możesz faktycznie zadeklarować pole jako publiczne ("publiczne" w cudzysłowie, bo w pythonie i tak do każdej wartości można się dostać), jeśli chcesz żeby to pole można było do woli odczytywać i zmieniać, albo możesz wystawić @property
oraz/lub dodając odpowiedni @property.setter
.