CodeGym /Kursy /Python SELF PL /Metody specjalne i pola

Metody specjalne i pola

Python SELF PL
Poziom 15 , Lekcja 5
Dostępny

5.1 Poziomy dostępu

Pewnie zauważyłeś dziwne imię konstruktora __init__? W przyszłości będziesz spotykać to dość często.

W Pythonie istnieją różne poziomy dostępu do atrybutów i metod klas, które pomagają kontrolować widoczność i bezpieczeństwo danych. Główne mechanizmy kontroli dostępu obejmują użycie jednego lub dwóch podkreśleń (_ i __) przed nazwą atrybutu lub metody.

Użycie konwencji

Jedno podkreślenie _ używane jest dla atrybutów i metod, które nie powinny być używane poza klasą lub modułem. To nie jest zakazane, ale to konwencja, którą należy przestrzegać dla lepszej czytelności i wsparcia kodu.

Dwa podkreślenia __ używane są dla atrybutów i metod, które powinny być naprawdę prywatne i chronione przed przypadkowym lub celowym dostępem z zewnątrz. Mechanizm name mangling czyni je mniej dostępnymi, ale nadal dostępnymi przez specjalne nazwy.

Publiczne (public) pola i metody

Publiczne atrybuty i metody dostępne są z dowolnego miejsca w kodzie. W Pythonie domyślnie wszystkie atrybuty i metody są publiczne, jeśli ich nazwy nie zaczynają się od podkreślenia.


class MyClass:
    def __init__(self):
        self.public_attribute = "I am public"
        
    def public_method(self):
        return "This is a public method"
        

obj = MyClass()
print(obj.public_attribute)  # Dostępne
print(obj.public_method())  # Dostępne

Przez poziomy dostępu w języku Python realizowana jest enkapsulacja, a mianowicie przez niepubliczne pola i metody.

5.2 Niepubliczne pola i metody

Chronione (protected) pola i metody

Chronione atrybuty i metody oznaczane są jednym podkreśleniem _ przed nazwą i przeznaczone są do wewnętrznego użycia w klasie i jej podklasach. To konwencja, która wskazuje programistom, że dane nie są przeznaczone do użycia poza klasą.


class MyClass:
    def __init__(self):
        self._protected_attribute = "I am protected"
        
    def _protected_method(self):
        return "This is a protected method"
        

obj = MyClass()
print(obj._protected_attribute)  # Dostępne, ale niezalecane
print(obj._protected_method())  # Dostępne, ale niezalecane

Prywatne (private) pola i metody

W Pythonie prywatne atrybuty i metody oznaczane są dwoma podkreśleniami __ przed nazwą. Te atrybuty i metody przeznaczone są do użycia wyłącznie wewnątrz klasy, a ich głównym celem jest ukrycie wewnętrznej implementacji i ochrona danych przed przypadkową zmianą lub użyciem z zewnątrz.

Aby zapobiec bezpośredniemu dostępowi do takich atrybutów i metod z zewnętrznego kodu, Python stosuje specjalny mechanizm, znany jako name mangling (zniekształcenie nazwy). Ten mechanizm automatycznie zmienia nazwy prywatnych atrybutów, dodając do nich prefiks z nazwą klasy. W ten sposób prywatny atrybut __private_attribute w klasie MyClass zostanie przekształcony na wewnętrzną nazwę _MyClass__private_attribute.

To pozwala chronić dane przed niezamierzonym dostępem, zachowując jednocześnie możliwość pracy z nimi wewnątrz klasy. Ważne jest jednak, by pamiętać, że mechanizm "name mangling" nie jest absolutną ochroną — doświadczony programista może uzyskać dostęp do tych danych, używając zmienionej nazwy.

Przyjrzyjmy się, jak to działa w praktyce:


class MyClass:
    def __init__(self):
        self.__private_attribute = "I am private"
        
    def __private_method(self):
        return "This is a private method"
        
    def access_private_method(self):
        return self.__private_method()
         

obj = MyClass()
# print(obj.__private_attribute)  # Błąd, niedostępne bezpośrednio
# print(obj.__private_method())  # Błąd, niedostępne bezpośrednio
print(obj.access_private_method())  # Dostępne przez publiczną metodę klasy

Jak widać na przykładzie, bezpośredni dostęp do prywatnych atrybutów lub metod powoduje błąd. Ale Python zostawia możliwość dostępu do nich przez zmienioną nazwę. Na przykład, można uzyskać dostęp do prywatnego atrybutu używając "zniekształconej" nazwy, jak pokazano poniżej:


class MyClass:
    def __init__(self):
        self.__private_attribute = "I am private"
   
obj = MyClass()
print(obj._MyClass__private_attribute)  # Wyświetli: I am private

Chociaż dostęp przez "zniekształconą" nazwę jest możliwy, należy tego unikać, ponieważ narusza to zasady enkapsulacji i może prowadzić do niestabilności kodu.

Aby zobaczyć, jak Python zmienia nazwy atrybutów, można użyć wbudowanej funkcji dir(), która wyświetla wszystkie dostępne atrybuty i metody obiektu:


class MyClass:
    def __init__(self):
        self.__private_attribute = "I am private"
   
obj = MyClass()
print(dir(obj))  # Wyświetla wszystkie atrybuty i metody obiektu, w tym "zniekształcone" nazwy

W wyniku wykonania funkcji dir() zobaczysz listę wszystkich atrybutów i metod obiektu, w tym _MyClass__private_attribute, co potwierdza mechanizm "name mangling".

5.3 Automatyczne wywołanie metod

Był jeden ciekawy aspekt przy pracy z konstruktorami, na który mogłeś zwrócić uwagę. Metoda __init__ była wywoływana automatycznie.

W rzeczywistości takich sytuacji jest dość dużo, jak i metod na te przypadki. Przykłady:

Metoda __str__

Jeśli twój obiekt ma metodę __str__, to będzie ona wywoływana automatycznie przy próbie konwersji twojego obiektu na ciąg znaków, na przykład przy użyciu funkcji print() i str().


class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age
            
    def __str__(self):
        return f"{self.name} is {self.age} years old"
            

cat = Cat("Barsik", 5)
print(cat)  # Wyświetli: Barsik is 5 years old

Metoda __len__

A jeśli twój obiekt ma metodę __len__, to będzie ona wywoływana automatycznie przy próbie określenia „długości” twojego obiektu — używane jest to przez funkcję len(). Przykład:


class MyList:
    def __init__(self, items):
        self.items = items
        
    def __len__(self):
        return len(self.items)
        
        
my_list = MyList([1, 2, 3])
print(len(my_list))  # Wyświetli: 3

Tego typu „metod specjalnych” będzie jeszcze wiele w twoim życiu, ale praca z nimi to czysta przyjemność. Zatem przygotuj się :)

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION