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