Почему Python использует два подчеркивания на определенные вещи?

StackOverflow https://stackoverflow.com/questions/3443043

  •  27-09-2019
  •  | 
  •  

Вопрос

Я довольно нового для реальных языков программирования, а Python - мой первый. Я немного знаю вокруг Linux, достаточно, чтобы получить летнюю работу с ним (я все еще в средней школе), и на работе у меня много свободного времени, которое я использую для изучения Python.

Одна вещь, хотя меня заставило. Что именно отличается в Python, когда у вас есть выражения, такие как

x.__add__(y) <==> x+y
x.__getattribute__('foo') <==> x.foo

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

PS, я не против, чтобы быть лекции по истории программирования, на самом деле, мне очень полезно знать :) Если это в основном исторические аспекты Python, не стесняйтесь начать бессвязку.

Это было полезно?

Решение

Ну, сила для программиста хорошая, поэтому должен быть способ настроить поведение. Как оператор перегрузки (__add__, __div__, __ge__, ...), доступ атрибута (__getattribute__, __getattr__ (эти два разных), __delattr__, ...) И т. Д. Во многих случаях, как операторы, обычные синтаксические карты 1: 1 к соответствующему способу. В других случаях существует специальная процедура, которая в какой-то момент включает в себя вызывающую соответствующий метод - например, __getattr__ называется только если объект не имеет запрошенного атрибута и __getattribute__ не реализован или поднят AttictueError. И некоторые из них являются действительно продвинутыми темами, которые вытесните вас в кишку системы объекта и редко нужны. Поэтому нет необходимости изучать их все, просто обратитесь к ссылке, когда вам нужно / хотите знать. Говоря об ссылке, вот.

Другие советы

Вот создатель Python объясняя его:

... вместо того, чтобы разработать новый синтаксис для особых видов методов классов (таких как инициализаторы и деструкторы), я решил, что эти функции могут быть обработаны, просто требуя пользователя реализовать методы со специальными именами, такими как __init__, __del__, и так далее. Эта Конвенция именования была взята из C, где идентификаторы, начинающиеся с подчеркивания, зарезервированы компилятором, и часто имеют особое значение (например, макросы, такие как __FILE__ в C Preprocessor).

...

Я также использовал эту технику, чтобы разрешить пользователю классы переопределить поведение операторов Python. Как отмечалось ранее, Python реализован в C и использует таблицы указателей функций для реализации различных возможностей встроенных объектов (например, «Получить атрибут», «Добавить» и «Вызов»). Чтобы разрешить эти возможности быть определены в пользовательских классах, я сопоставил различные указатели функции на специальные имена методов, таких как __getattr__, __add__, а также __call__. Отказ Существует прямая переписка между этими именами, а таблицы указателей функций необходимо определить при реализации новых объектов Python в C.

Когда вы начинаете метод с двумя подчеркиваниями (и без трейлинга подчеркивания), Python's Наименование понравился Правила применяются. Это способ свободно имитировать private Ключевое слово из других языков OO, таких как C ++ и Java. (Тем не менее, метод по-прежнему технически не является частным тем, как методы Java и C ++ являются частными, но это «сложнее попасть» снаружи экземпляра.)

Методы с двумя ведущими и двумя задними подчеркиваниями считаются «встроенными» методами, то есть они используются переводчиком и, как правило, являются конкретными реализациями перегруженных операторов или других встроенных функциональных возможностей.

Они используются для указания того, что интерпретатор Python должен использовать их в определенных ситуациях.

Например, то __add__ Функция позволяет + Оператор для работы для пользовательских классов. В противном случае вы получите некоторую не определенную ошибку при попытке добавления.

С исторической точки зрения, ведущие подчеркивания часто использовались в качестве метода, указывающего на программист, что имена должны быть рассмотрены внутренними на пакет / модуль / библиотеку, которая их определяет. На языках, которые не предоставляют хорошую поддержку для частных пространств имен, используя подчеркивания - это конвенция для эмуляции этого. В Python, когда вы определяете метод, названный «__foo__», программист обслуживания знает из имени, что происходит что-то особенное, которое не происходит с методом, названным «foo». Если Python выбрал использовать «Добавить» в качестве внутреннего метода для перегрузки «+», то у вас никогда не может быть класса с методом «Добавить», не вызывая большого путаницы. Подчеркивание служит царом, что произойдет некоторая магия.

Ряд других вопросов теперь отмечены как дубликаты этого вопроса, и, по крайней мере, два из них спрашивают, что либо __spam__ Способы называются, или то, что называется Конвенция, и ни один из существующих ответов охватывает это, так:

На самом деле нет официального имени.

Многие разработчики неофициально называют их «Dunder Methods», для «двойной подчеркивания».

Некоторые люди используют термин «магические методы», но это несколько неоднозначно между смыслом распознавания диаметрами, специальными методами (см. Ниже) или что-то где-то между ними.


Там является Официальный термин «особые атрибуты», который тесно совпадает, но не полностью с методами разума. То Модель данных Глава в ссылке никогда не совсем объясняет, что такое специальный атрибут, но основная идея состоит в том, что это, по крайней мере, одно из следующих действий:

  • Атрибут, который предоставлен самим интерпретатором или его встроенным кодом, как __name__ на функцию.
  • Атрибут, который является частью протокола, реализованного самим интерпретатором, как __add__ для + Оператор или __getitem__ для индексации и нарезки.
  • Атрибут того, что интерпретатор разрешено просматривать специально, игнорируя экземпляр и идти прямо на класс, как __add__ опять таки.

Большинство специальных атрибутов являются методы, но не все (например, __name__ не). И больше всего используют «Дундер» Конвенцию, но не все (например, next Способ на итераторах в Python 2.x).

И тем временем, большинство методов Dunder - это особые атрибуты, но не все, в частности, не совсем нельзя для STDLib или внешних библиотек, чтобы захотеть определить свои собственные протоколы, которые работают так же, как pickle протокол.

Спекуляция Python был под влиянием Algol68., Гвидо возможно, используемый Algol68 на Университет Амстердама где algol68 имеет похоже "Практический режим«под названием« цитата строппинг ». В Algol68 Операторы, типы и ключевые слова могу появляются в другом шрифте (обычно **жирный**, или __underlined.__), в файлах Sourcecode этот шрифт достигается с цитатами, например, «ABS» (цитируя аналогично цитирующему в «wikitext.')

ALGOL68 ⇒ Python (операторы сопоставлены на функции членов)

  • 'и' ⇒ __ и __
  • 'или' ⇒ __OR__
  • «не» ⇒ не
  • 'inger' ⇒ __trunc__
  • 'shl' ⇒ __lshift__
  • «ШР» ⇒ __rshift__
  • «UPB» ⇒ __sizeof__
  • «длинный» ⇒ __long__
  • 'int' ⇒ __int__
  • «Реальный» ⇒ __float__
  • «Формат» ⇒ __Format__
  • 'repra' ⇒ __repr__
  • 'abs' ⇒ __abs__
  • «минус» ⇒ __neg__
  • «минус» ⇒ __sub__
  • 'plus' ⇒ __add__
  • 'Times' ⇒ __mul__
  • 'mod' ⇒ __mod__
  • 'div' ⇒ __truediv__
  • «За» ⇒ __div__
  • 'up' ⇒ __pow__
  • 'im' ⇒ imag
  • 'Re' ⇒ Real
  • «Сопряжение» ⇒ конъюгат

В ALGOL68 их называли смелые имена, например, пресс, но «под недооценка» __abs__ в Python.

Мои 2 цента: ¢ так иногда - как призрак - когда вы вырезаете и вставляете классы Python в вики, вы будете волшебным реинкаргом Algol68's жирный ключевые слова. ¢.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top