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

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

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

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

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

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

51
задан sth 9 August 2010 в 07:56
поделиться

5 ответов

Well, power for the programmer is good, so there should be a way to customize behaviour. Like operator overloading (__add__, __div__, __ge__, ... ), attribute access (__getattribute__, __getattr__ (those two are differnt), __delattr__, ...) etc. In many cases, like operators, the usual syntax maps 1:1 to the respective method. In other cases, there is a special procedure which at some point involves calling the respective method - for example, __getattr__ is only called if the object doesn't have the requested attribute and __getattribute__ is not implemented or raised AttributeError. And some of them are really advanced topics that get you deeeeep into the object system's guts and are rarely needed. So no need to learn them all, just consult the reference when you need/want to know. Speaking of reference, here it is.

7
ответ дан 7 November 2019 в 10:20
поделиться

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

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

...

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

29
ответ дан 7 November 2019 в 10:20
поделиться

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

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

4
ответ дан 7 November 2019 в 10:20
поделиться

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

3
ответ дан 7 November 2019 в 10:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: