Подтвердить что ты не робот

Какова цель унарного оператора + (pos) в Python?

Вообще говоря, что должен делать унарный + в Python?

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

+obj != obj

Где obj - общий объект, реализующий __pos__().

Итак, мне интересно: почему существуют + и __pos__()? Можете ли вы представить пример реального мира, в котором выражение выше оценивается как True?

4b9b3361

Ответ 1

Вот пример "реального мира" из пакета decimal:

>>> from decimal import Decimal
>>> obj = Decimal('3.1415926535897932384626433832795028841971')
>>> +obj != obj  # The __pos__ function rounds back to normal precision
True
>>> obj
Decimal('3.1415926535897932384626433832795028841971')
>>> +obj
Decimal('3.141592653589793238462643383')

Ответ 2

Я полагаю, что операторы Python, вдохновленные C, где для симметрии был введен оператор + (а также некоторые полезные хаки, см. комментарии).

В слабо типизированных языках, таких как PHP или Javascript, + сообщает исполняемой среде об увеличении значения переменной в число. Например, в Javascript:

   +"2" + 1
=> 3
   "2" + 1
=> '21'

Python строго типизирован, поэтому строки не работают как числа и, как таковые, не реализуют унарный оператор plus.

Конечно, возможно реализовать объект, для которого + obj!= obj:

>>> class Foo(object):
...     def __pos__(self):
...        return "bar"
... 
>>> +Foo()
'bar'
>>> obj = Foo()
>>> +"a"

Что касается примера, для которого это действительно имеет смысл, проверьте сюрреалистические номера. Это надмножество реалов, которое включает бесконечно малые значения (+ эпсилон, - эпсилон), где epsilon положительное значение, меньшее любого другого положительного числа, но больше 0; и бесконечные (+ бесконечность, - бесконечность).

Вы можете определить epsilon = +0 и -epsilon = -0.

Пока 1/0 по-прежнему undefined, 1/epsilon = 1/+0 есть +infinity и 1/-epsilon= -infinity. это не более, чем принимать пределы 1/x как x aproaches 0 справа (+) или слева (-).

Поскольку 0 и +0 ведут себя по-разному, имеет смысл, что 0 != +0.

Ответ 3

В Python 3.3 и выше collections.Counter использует оператор + для удаления неположительных счетчиков.

>>> from collections import Counter
>>> fruits = Counter({'apples': 0, 'pears': 4, 'oranges': -89})
>>> fruits
Counter({'pears': 4, 'apples': 0, 'oranges': -89})
>>> +fruits
Counter({'pears': 4})

Итак, если у вас есть отрицательные или нулевые значения в Counter, у вас есть ситуация, когда +obj != obj.

>>> obj = Counter({'a': 0})
>>> +obj != obj
True

Ответ 4

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

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

  • + может утверждать для положительности и исключать исключение, если это не так - очень полезно обнаруживать угловые случаи.
  • Объект может быть многозначным (подумайте ±sqrt(z) как единый объект - для решения квадратичных уравнений для разномасштабных аналитических функций, где угодно, где вы можете "свернуть" двоякую функцию в одну ветвь со знаком, включая ± 0, упомянутый vlopez.
  • Если вы делаете ленивую оценку, это может создать объект функции, который добавляет что-то к тому, что он применяется к чему-то другому. Например, если вы постепенно увеличиваете арифметику.
  • Как функция идентификации, которая передается в качестве аргумента для некоторого функционала.
  • Для алгебраических структур, где знак накапливает - лестничные операторы и т.д. Конечно, это можно сделать с помощью других функций, но можно было бы увидеть нечто вроде y=+++---+++x. Более того, им не нужно ездить на работу. Это создает свободную группу плюсов и минусов, которые могут быть полезны. Даже в формальных реализациях грамматики.
  • Дикое использование: оно может "пометить" шаг в вычислении как "активный" в некотором смысле. система reap/sow - каждый плюс запоминает значение, и в конце вы можете собрать собранные промежуточные продукты... потому что почему бы и нет?

Это, плюс все причины приведения типов, упомянутые другими.

И в конце концов... приятно иметь еще один оператор, если он вам нужен.

Ответ 5

__pos__() существует в Python, чтобы дать программистам аналогичные возможности, как в языке C++, - перегрузить операторы, в этом случае унарный оператор +.

(Перегрузочные операторы означают, что они имеют различное значение для разных объектов, например, двоичный + ведет себя по-разному для чисел, а для строк - числа добавляются при объединении строк.)

Объекты могут реализовывать (помимо других) эти эмулятивные числовые типы функций (методов):

    __pos__(self)             # called for unary +
    __neg__(self)             # called for unary -
    __invert__(self)          # called for unary ~

Итак, +object означает то же самое, что и object.__pos__() - они взаимозаменяемы.

Однако +object легче на глаза.

Создатель конкретного объекта имеет свободные руки для реализации этих функций, как он хочет - как показали другие люди в своих реальных примерах.

И мой вклад - как шутка: ++i != +i в C/С++.