6

Почему у некоторых функций есть двойные подчеркивания "__" перед и после имени функции?

29

Вопрос о подчеркивании в именах функций в Python

Я заметил, что подчеркивания в именах функций и переменных в Python встречаются довольно часто, и мне интересно, является ли это требованием языка или всего лишь соглашением о стиле?

Кроме того, не могли бы вы перечислить и объяснить, какие функции обычно имеют подчеркивания, и почему (например, __init__)?

5 ответ(ов)

0

Другие ответчики правы, описывая двойные подчеркивания в начале и конце имени как соглашение о наименовании для "специальных" или "магических" методов.

Хотя вы можете вызывать эти методы напрямую (например, [10, 20].__len__()), наличие подчеркиваний указывает на то, что эти методы предназначены для косвенного вызова (например, len([10, 20])). Большинство операторов в Python имеют соответствующий "магический" метод (например, a[x] — это обычный способ вызова a.__getitem__(x)).

0

Добавил пример для понимания использования __ в Python. Вот список всех __

https://docs.python.org/3/genindex-all.html#_

Определённые классы идентификаторов (кроме ключевых слов) имеют особое значение. Любое использование * имен, в любом другом контексте, не соответствующее явно задокументированному использованию, подвержено поломке без предупреждения.

Ограничение доступа с помощью __

"""
Идентификаторы:
- Содержат только (A-z, 0-9 и _)
- Начинаются с строчной буквы или _
- Один ведущий _ : частный
- Два ведущих __ : строго частный
- Начинается и заканчивается __ : специальное имя объекта/метода, определяемое языком
- Имена классов начинаются с заглавной буквы.
"""

class BankAccount(object):
    def __init__(self, name, money, password):
        self.name = name            # Публичный
        self._money = money         # Приватный: уровень пакета
        self.__password = password  # Супер приватный

    def earn_money(self, amount):
        self._money += amount
        print("Зарплата получена: ", amount, " Обновлённый баланс: ", self._money)

    def withdraw_money(self, amount):
        self._money -= amount
        print("Деньги сняты: ", amount, " Обновлённый баланс: ", self._money)

    def show_balance(self):
        print(" Текущий баланс: ", self._money)

account = BankAccount("Hitesh", 1000, "PWD")  # Инициализация объекта

# Вызов метода
account.earn_money(100)

# Показать баланс
print(account.show_balance())

print("ПУБЛИЧНЫЙ ДОСТУП:", account.name)  # Публичный доступ

# account._money доступен, потому что он только скрыт в соответствии с соглашением
print("ЗАЩИЩЁННЫЙ ДОСТУП:", account._money)  # Защищённый доступ

# account.__password вызовет ошибку, но account._BankAccount__password не вызовет,
# потому что __password - сверхприватный
print("ЧАСТНЫЙ ДОСТУП:", account._BankAccount__password)

# Вызов метода
account.withdraw_money(200)

# Показать баланс
print(account.show_balance())

# account._money доступен, потому что он только скрыт в соответствии с соглашением
print(account._money)  # Защищённый доступ

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

0

Использование метода с нижним подчеркиванием в именах действительно является распространенной практикой, особенно когда нужно различать методы родительского и дочернего классов. Это позволяет избежать конфликтов имен и явно указывает на то, что метод _worker предназначен для переопределения в дочернем классе.

В вашем примере вы используете миксин ThreadableMixin, который реализует метод start_worker, вызывающий метод worker. Важно отметить, что внутри этого метода происходит вызов _worker - это говорит о том, что вы ожидаете, что дочерний класс реализует этот метод, предоставляя свою собственную логику.

Пример кода, который вы представили, демонстрирует, как в классе Handler переопределяется метод _worker. Вопреки обычной практике именования, использование нижнего подчеркивания в начале имени метода (_worker) указывает на то, что он предназначен для внутреннего использования, но при этом позволяет дочерним классам реализовать собственную версию этого метода. Это полезно для управления наследованием, так как соблюдается определенная структура и предсказуемость, когда дело доходит до работы с методами.

Таким образом, данная практика помогает поддерживать чистоту и организованность кода, а также облегчает понимание его структуры другими разработчиками.

0

Данная конвенция используется для специальных переменных или методов (так называемых "магических методов"), таких как __init__ и __len__. Эти методы обеспечивают специальные синтаксические функции или выполняют определённые действия.

Например, __file__ указывает на расположение файла Python, а __eq__ вызывается при выполнении выражения a == b.

Пользователь, конечно, может создать свой собственный специальный метод, что является довольно редким случаем, но чаще всего может изменять некоторые из встроенных специальных методов (например, инициализация класса с помощью __init__, который выполняется первым при создании экземпляра класса).

class A:
    def __init__(self, a):  # используем специальный метод '__init__' для инициализации
        self.a = a
    def __custom__(self):  # кастомный специальный метод. Его можно почти не использовать
        pass
0

В Python использование подчеркивания в имени функции указывает на то, что функция предназначена для внутреннего использования и не должна вызываться напрямую пользователями. Это соглашение, которое показывает, что функция является "приватной" и не входит в публичный API модуля. Однако следует отметить, что это соглашение не является строгим ограничением, и пользователи все равно могут вызывать такую функцию, если они решат это сделать.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь