Почему некоторые функции подчеркивают "__" до и после имени функции?
Это, кажется, происходит много, и было интересно, было ли это требованием на языке Python или просто вопросом конвенции?
Кроме того, может ли кто-то назвать и объяснить, какие функции имеют тенденцию иметь символы подчеркивания и почему (__init__
, например)?
Ответы
Ответ 1
Из Python PEP 8 - Руководство по стилю для кода Python:
Следующие специальные формы с использованием ведущих или завершающих подчеркиваний (они обычно могут быть объединены с любым случаем):
-
_single_leading_underscore
: слабый индикатор "внутреннего использования". Например. from M import *
не импортирует объекты, имя которых начинается с подчеркивания.
-
single_trailing_underscore_
: используется по соглашению, чтобы избежать конфликтов с ключевым словом Python, например
Tkinter.Toplevel(master, class_='ClassName')
-
__double_leading_underscore
: при присвоении имени атрибуту класса вызывается обращение к имени (внутри класса FooBar, __boo
становится _FooBar__boo
, см. ниже).
-
__double_leading_and_trailing_underscore__
: "магические" объекты или атрибуты, которые находятся в контролируемых пользователем пространствах имен. Например. __init__
__import__
или __file__
. Никогда не изобретайте такие имена; используйте их только как задокументированные.
Обратите внимание, что имена с двойными ведущими и завершающими символами подчеркивания по существу зарезервированы для самого Python: "Никогда не изобретайте такие имена, используйте их только как документально".
Ответ 2
Другие респонденты правильны в описании двойных ведущих и завершающих подчеркиваний в качестве соглашения об именах для "специальных" или "магических" методов.
Хотя вы можете напрямую вызвать эти методы (например, [10, 20].__len__()
), наличие подчеркиваний - это намек на то, что эти методы предназначены для косвенного вызова (например, len([10, 20])
). Большинство операторов python имеют связанный "магический" метод (например, a[x]
- обычный способ вызова a.__getitem__(x)
).
Ответ 3
Имена, окруженные двойными подчеркиваниями, являются "специальными" для Python. Они перечислены в Справочник по языку Python, раздел 3, "Модель данных" .
Ответ 4
На самом деле я использую имена методов, когда мне нужно различать имена родительского и дочернего классов. Я прочитал несколько кодов, которые использовали этот способ создания родительских классов. В качестве примера я могу предоставить этот код:
class ThreadableMixin:
def start_worker(self):
threading.Thread(target=self.worker).start()
def worker(self):
try:
self._worker()
except tornado.web.HTTPError, e:
self.set_status(e.status_code)
except:
logging.error("_worker problem", exc_info=True)
self.set_status(500)
tornado.ioloop.IOLoop.instance().add_callback(self.async_callback(self.results))
...
и ребенок, у которого есть метод _worker
class Handler(tornado.web.RequestHandler, ThreadableMixin):
def _worker(self):
self.res = self.render_string("template.html",
title = _("Title"),
data = self.application.db.query("select ... where object_id=%s", self.object_id)
)
...
Ответ 5
Это соглашение используется для специальных переменных или методов (так называемый "магический метод"), таких как __init__, len. Эти методы предоставляют специальные синтаксические функции или делают специальные вещи.
Например, file указывает местоположение файла Python, eq выполняется, когда выполняется выражение == b.
Пользователь, конечно, может создать специальный специальный метод, это очень редкий случай, но часто может изменить некоторые встроенные специальные методы. (Например, вы должны инициализировать класс с помощью init, который будет выполняться сначала при создании экземпляра класса.)
class A:
def __init__(self, a): # use special method '__init__' for initializing
self.a = a
def __custom__(self): # custom special method. you might almost do not use it
pass