Menu
Coddy logo textTech

Модификаторы доступа

Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 29 из 64.

Модификаторы доступа управляют видимостью атрибутов и методов класса. Python использует соглашения об именовании, а не ключевые слова для управления доступом.

Вот пример публичного доступа (без префикса):

class Person:
    def __init__(self):
        self.name = "Coddy"      # Публичный атрибут
        
    def greet(self):             # Публичный метод
        return f"Hello, I'm {self.name}"

Доступ к публичным членам из любого места:

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Привет, я Coddy

Вот пример защищенного доступа (одинарное подчеркивание):

class Employee:
    def __init__(self):
        self._salary = 50000     # Защищенный атрибут
    
    def _calculate_bonus(self):  # Защищенный метод
        return self._salary * 0.1

    def show_bonus(self):
        return self._calculate_bonus()  # Можно использовать внутри класса

Доступ к защищенным членам (работает, но не рекомендуется):

employee = Employee()
print(employee._salary)      # 50000 - работает, но не рекомендуется
print(employee.show_bonus()) # 5000.0 - правильный способ

Вот пример приватного доступа (двойное подчеркивание):

class User:
    def __init__(self):
        self.__password = "secure123"   # Приватный атрибут
        
    def __encrypt(self, data):          # Приватный метод
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        # Приватные члены доступны внутри класса
        return input_password == self.__password

Используйте приватные члены правильно:

user = User()
print(user.verify("secure123"))  # True - использование публичного метода
# print(user.__password)         # AttributeError - невозможно получить доступ напрямую

Вывод:

Coddy
Hello, I'm Coddy
50000
5000.0
True

Ключевой момент: Модификаторы доступа Python — это соглашения об именовании: отсутствие префикса = public (доступен отовсюду), одиночное подчеркивание = protected (для внутреннего использования), двойное подчеркивание = private (только внутри класса). Они помогают установить четкие границы и предотвратить случайное неправильное использование внутренних механизмов класса.

challenge icon

Задание

Средне

В этом испытании вы реализуете класс FileManager, который демонстрирует модификаторы доступа Python (публичные, защищенные и приватные), одновременно изучая преимущества комплексного тестирования.

Отредактируйте файл filemanager.py, чтобы реализовать класс FileManager, следуя комментариям TODO. Файл содержит подробные инструкции по реализации:

  • Публичные методы для операций с файлами
  • Защищенные методы (с префиксом в виде одного подчеркивания)
  • Приватные методы (с префиксом в виде двойного подчеркивания)
  • Взаимодействие методов, демонстрирующее инкапсуляцию

Шпаргалка

Python использует соглашения об именовании для управления доступом:

Публичный доступ (без префикса) — доступен отовсюду:

class Person:
    def __init__(self):
        self.name = "Coddy"      # Публичный атрибут
        
    def greet(self):             # Публичный метод
        return f"Hello, I'm {self.name}"

person = Person()
print(person.name)           # Coddy
print(person.greet())        # Hello, I'm Coddy

Защищенный доступ (одинарное подчеркивание) — для внутреннего использования, не рекомендуется обращаться извне:

class Employee:
    def __init__(self):
        self._salary = 50000     # Защищенный атрибут
    
    def _calculate_bonus(self):  # Защищенный метод
        return self._salary * 0.1

employee = Employee()
print(employee._salary)      # Работает, но не рекомендуется

Приватный доступ (двойное подчеркивание) — только внутри класса:

class User:
    def __init__(self):
        self.__password = "secure123"   # Приватный атрибут
        
    def __encrypt(self, data):          # Приватный метод
        return f"Encrypted: {data}"
        
    def verify(self, input_password):
        return input_password == self.__password

user = User()
print(user.verify("secure123"))  # True — использование публичного метода
# print(user.__password)         # AttributeError — нельзя получить доступ напрямую

Попробуйте сами

from file_manager import FileManager

# Комплексный обработчик тестовых случаев
test_case = input()

if test_case == "basic_test":
    # Создать экземпляр FileManager
    manager = FileManager()
    # Вызвать метод read_file
    print(manager.read_file("example.txt"))
    # Вызвать метод get_file_content
    print(manager.get_file_content("example.txt"))

elif test_case == "protected_access":
    # Создать экземпляр FileManager
    manager = FileManager()
    # Попробовать вызвать защищенный метод
    # Защищенные методы доступны, но предназначены для внутреннего использования
    print(manager._check_permissions("example.txt"))
    print("Note: Protected methods are accessible but intended for internal use only")

elif test_case == "private_access":
    # Создать экземпляр FileManager
    manager = FileManager()
    try:
        # Попробовать вызвать приватный метод напрямую
        print(manager.__decrypt_content("some content"))
    except AttributeError as e:
        print(f"Error: {e}")
        print("Private methods are name-mangled and cannot be accessed directly")
    
    # Доступ с использованием искаженного имени (name-mangling)
    print(manager._FileManager__decrypt_content("some content"))
    print("Note: Accessed private method using name-mangled form")

elif test_case == "method_chaining":
    # Создать экземпляр FileManager
    manager = FileManager()
    # Продемонстрировать, как get_file_content внутренне вызывает как защищенные, так и приватные методы
    print("Calling get_file_content which internally uses protected and private methods:")
    print(manager.get_file_content("example.txt"))

elif test_case == "multiple_files":
    # Создать экземпляр FileManager
    manager = FileManager()
    # Обработать несколько файлов
    files = ["document.txt", "image.jpg", "data.csv"]
    
    for file in files:
        print(f"\
Processing {file}:")
        print(manager.read_file(file))
        print(manager.get_file_content(file))

elif test_case == "name_mangling":
    # Создать экземпляр FileManager
    manager = FileManager()
    # Продемонстрировать искажение имен (name mangling)
    print("Python's name mangling for private methods:")
    print("Attempting direct access would fail with AttributeError")
    print("Using mangled name:")
    print(manager._FileManager__decrypt_content("private data"))
    print("\
Name mangling is Python's mechanism to prevent accidental access")
    print("It renames __method to _ClassName__method internally")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming