JavaRush /Курсы /Модуль 1: Python Core /Служебные методы и поля

Служебные методы и поля

Модуль 1: Python Core
9 уровень , 4 лекция
Открыта

5.1 Уровни доступа

Вы, наверное, обратили внимание на странное имя конструктора __init__? В будущем вы будете встречать такое довольно часто.

В Python существуют различные уровни доступа к атрибутам и методам классов, которые помогают контролировать видимость и защищённость данных. Основные механизмы управления доступом включают использование одного или двух подчёркиваний (_ и __) перед именем атрибута или метода.

Использование соглашений

Одно подчёркивание _ используется для атрибутов и методов, которые не должны использоваться вне класса или модуля. Это не запрещено, но это соглашение, которое следует соблюдать для лучшей читаемости и поддержки кода.

Два подчёркивания __ используются для атрибутов и методов, которые должны быть действительно приватными и защищёнными от случайного или намеренного доступа извне. Механизм name mangling делает их менее доступными, но всё ещё доступными через специальные имена.

Публичные (public) поля и методы

Публичные атрибуты и методы доступны из любого места кода. В Python по умолчанию все атрибуты и методы публичны, если их имена не начинаются с подчёркивания.


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)  # Доступно
print(obj.public_method())  # Доступно

Через уровни доступа в языке Python реализуется инкапсуляция, а именно через непубличные поля и методы.

5.2 Непубличные поля и методы

Защищённые (protected) поля и методы

Защищённые атрибуты и методы обозначаются одним подчёркиванием _ перед именем и предназначены для внутреннего использования в классе и его подклассах. Это соглашение, которое говорит программистам о том, что данные не предназначены для использования вне класса.


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)  # Доступно, но не рекомендуется
print(obj._protected_method())  # Доступно, но не рекомендуется

Приватные (private) поля и методы

В Python приватные атрибуты и методы обозначаются двумя подчёркиваниями __ перед именем. Эти атрибуты и методы предназначены для использования исключительно внутри класса, и их основная цель — скрыть внутреннюю реализацию и защитить данные от случайного изменения или использования извне.

Чтобы предотвратить прямой доступ к таким атрибутам и методам из внешнего кода, Python применяет специальный механизм, известный как name mangling (искажение имени). Этот механизм автоматически изменяет имена приватных атрибутов, добавляя к ним префикс, состоящий из имени класса. Таким образом, приватный атрибут __private_attribute в классе MyClass будет преобразован во внутреннее имя _MyClass__private_attribute.

Это позволяет защитить данные от непреднамеренного доступа, сохраняя при этом возможность работы с ними внутри класса. Однако, важно помнить, что механизм "name mangling" не является абсолютной защитой — опытный программист может получить доступ к этим данным, используя изменённое имя.

Давайте рассмотрим, как это работает на практике:


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)  # Ошибка, недоступно напрямую
# print(obj.__private_method())  # Ошибка, недоступно напрямую
print(obj.access_private_method())  # Доступно через публичный метод класса

Как видно из примера, прямой доступ к приватным атрибутам или методам вызывает ошибку. Но Python сохраняет возможность доступа к ним через изменённое имя. Например, вы можете получить доступ к приватному атрибуту с использованием "искажённого" имени, как показано ниже:


class MyClass:
    def __init__(self):
        self.__private_attribute = "I am private"
   
obj = MyClass()
print(obj._MyClass__private_attribute)  # Выведет: I am private

Хотя доступ через "искажённое" имя возможен, этого следует избегать, так как это нарушает принципы инкапсуляции и может привести к нестабильности кода.

Чтобы увидеть, как Python изменяет имена атрибутов, вы можете использовать встроенную функцию dir(), которая отображает все доступные атрибуты и методы объекта:


class MyClass:
    def __init__(self):
        self.__private_attribute = "I am private"
   
obj = MyClass()
print(dir(obj))  # Выводит все атрибуты и методы объекта, включая "искажённые" имена

В результате выполнения функции dir() вы увидите список всех атрибутов и методов объекта, включая _MyClass__private_attribute, что подтверждает механизм "name mangling".

5.3 Автоматический вызов методов

Был один интересный аспект при работе с конструкторами, на который вы, возможно, обратили внимание. Метод __init__ вызывался автоматически.

На самом деле таких ситуаций довольно много, как и методов на эти случаи. Примеры:

Метод __str__

Если у вашего объекта есть метод __str__, то он будет вызван автоматически при попытке преобразовать ваш объект в строку, например, при использовании функций print() и 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)  # Выведет: Barsik is 5 years old

Метод __len__

А если у вашего объекта есть метод __len__, то он будет вызван автоматически при попытке определить «длину» вашего объекта — используется функцией len(). Пример:


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))  # Выведет: 3

Таких «служебных методов» ещё будет много в вашей жизни, но работать с ними одно удовольствие. Так что готовьтесь :)

2
Задача
Модуль 1: Python Core, 9 уровень, 4 лекция
Недоступна
Защищайтесь.
Защищайтесь.
2
Задача
Модуль 1: Python Core, 9 уровень, 4 лекция
Недоступна
Библиотека.
Библиотека.
Комментарии (8)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Анатолий Уровень 53
3 февраля 2026
❤️
Станислав Уровень 22
13 марта 2025
Прикольно, внезапно появились getters and setters, про которые новички явно не знают
SWK Уровень 26
5 апреля 2025
Во-первых, в явном виде не появились, во-вторых, студентов целенаправленно подводят к идее геттеров и сеттеров[, в-третьих, @setter в курсе упоминался]. Т.е., нормально всё.
Mr.Robot Уровень 21 Expert
9 марта 2025
Чего-то во второй задаче половину кода за меня уже написали... И автотесты - тоже )))
SWK Уровень 26
5 апреля 2025
По-хорошему, так и должно быть.
Екатерина Уровень 93
15 августа 2024
Вторая задача. Если не понятно, что вывести по условию "В классе Library должен быть метод __str__, который возвращает строковую информацию о библиотеке.", у меня валидатор меня принял такой ответ: Библиотека содержит книги: {перечисление_названий_книг}
Екатерина Уровень 93
15 августа 2024
Для первой задачи нужно прочитать про концепцию геттеров и сеттеров. Например, первая попавшаяся ссылка https://pylot.me/article/29-primenenie-getter-i-setter-metodov-dlya-zakritih-atributov-klassov/
Dmitry Ryabov Уровень 23
4 февраля 2025
Можно также сюда добавить и вот такую статейку ссылка