What's the purpose of the + (pos) unary operator in Python?

Here's a "real-world" example from the decimal package:

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

I believe that Python operators where inspired by C, where the + operator was introduced for symmetry (and also some useful hacks, see comments).

In weakly typed languages such as PHP or Javascript, + tells the runtime to coerce the value of the variable into a number. For example, in Javascript:

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

Python is strongly typed, so strings don't work as numbers, and, as such, don't implement an unary plus operator.

It is certainly possible to implement an object for which +obj != obj :

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

As for an example for which it actually makes sense, check out the surreal numbers. They are a superset of the reals which includes infinitesimal values (+ epsilon, - epsilon), where epsilon is a positive value which is smaller than any other positive number, but greater than 0; and infinite ones (+ infinity, - infinity).

You could define epsilon = +0, and -epsilon = -0.

While 1/0 is still undefined, 1/epsilon = 1/+0 is +infinity, and 1/-epsilon = -infinity. It is nothing more than taking limits of 1/x as x aproaches 0 from the right (+) or from the left (-).

As 0 and +0 behave differently, it makes sense that 0 != +0.


In Python 3.3 and above, collections.Counter uses the + operator to remove non-positive counts.

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

So if you have negative or zero counts in a Counter, you have a situation where +obj != obj.

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

Tags:

Python