Почему некоторые функции имеют подчеркивание "__" до и после имени функции? - PullRequest
372 голосов
/ 31 декабря 2011

Это, кажется, происходит много, и было интересно, было ли это требованием в языке Python или просто условием?

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

Ответы [ 6 ]

474 голосов
/ 31 декабря 2011

Из 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: «Никогда не изобретайте такие имена; используйте их только как документированные».

50 голосов
/ 01 января 2012

Остальные респонденты правы в описании двойных начальных и конечных подчеркиваний как соглашения об именах для «специальных» или «магических» методов.

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

15 голосов
/ 31 декабря 2011

Имена, окруженные двойным подчеркиванием, являются «особенными» для Python. Они перечислены в справочнике по языкам Python, раздел 3, «Модель данных» .

5 голосов
/ 30 августа 2015

На самом деле я использую имена методов _, когда мне нужно различать имена родительских и дочерних классов.Я прочитал некоторые коды, которые использовали этот способ создания родительско-дочерних классов.В качестве примера я могу предоставить этот код:

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)
    )

...

0 голосов
/ 04 марта 2019

Задний двойной знак подчеркивания (название искажения) / Из документов Python

Любой идентификатор вида __spam (как минимум два ведущих символа подчеркивания, не более одного завершающего подчеркивания) заменяется на текст _classname__spam, где classname - это текущее имя класса с начальными символами подчеркивания. Это искажение сделано без учета к синтаксической позиции идентификатора, так что он может быть использован для определить частный экземпляр класса и переменные класса, методы, переменные хранятся в глобальных переменных, и даже переменные хранятся в экземплярах. личное для этот класс на экземплярах других классов.

Имя искажения предназначено, чтобы дать классам легкий способ определить «Частные» переменные и методы экземпляра, не беспокоясь о переменных экземпляра, определенных производными классами, или с переменные экземпляра по коду вне класса. Обратите внимание, что искажение правила разработаны главным образом, чтобы избежать несчастных случаев; это все еще возможно для решительная душа для доступа или изменения переменной, которая считается частный.

0 голосов
/ 17 января 2019

Это соглашение используется для специальных переменных или методов (так называемый «магический метод»), таких как __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
...