Python中+(pos)一元运算符的用途是什么?
一般来说,一元+
在Python中应该做什么?
我问,因为到目前为止,我从未见过这样的情况:
+obj != obj
其中obj
是实现__pos__()
的通用对象。
所以我想知道:为什么有+
和__pos__()
存在? 你能提供一个真实世界的例子,上面的expression式评估为True
?
下面是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')
我相信Python运算符的灵感来自于C,其中+
运算符被引入对称(也是一些有用的黑客,见注释)。
在PHP或Javascript等弱types语言中,+会告诉运行时将variables的值强制为一个数字。 例如,在Javascript中:
+"2" + 1 => 3 "2" + 1 => '21'
Python是强types的,所以string不能用作数字,因此不要实现一元加运算符。
当然可以实现+ obj!= obj的对象:
>>> class Foo(object): ... def __pos__(self): ... return "bar" ... >>> +Foo() 'bar' >>> obj = Foo() >>> +"a"
至于其实际上有意义的例子,请查看超现实的数字 。 它们是包含无穷小值(+ epsilon, – epsilon)的实数的超集,其中epsilon是小于任何其他正数的正数,但大于0; 和无限的(+无限, – 无限)。
你可以定义epsilon = +0
, -epsilon = -0
。
虽然1/0
仍未定义,但是1/epsilon = 1/+0
是+infinity
, 1/-epsilon
= -infinity
。 只不过是把右边(+)或左边( – )的1/x
限制为0
。
由于0
和+0
行为不同,所以0 != +0
是有意义的。
在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
。
>>> +fruits != fruits True
为了对称,因为一元减号是一个操作符,所以一元加号也必须是。 在大多数的算术情况下,它什么都不做,但是要记住,用户可以定义任意的类并且使用这些算子来实现他们想要的任何东西,即使它不是严格的代数。
我知道这是一个古老的线索,但我想扩大现有的答案,以提供更广泛的例子:
-
+
可以断言积极性,并抛出exception,如果它不是非常有用的检测angular落案件。 - 对象可以是多值的(思考
±sqrt(z)
作为单个对象 – 用于求解二次方程,多分支分析函数,任何可以将一个二值函数“折叠”成一个带有符号的分支的东西,包括±0案例vlopez提到。 - 如果你做了懒惰的评估,这可能会创build一个函数对象,添加一些东西,无论它被应用到别的东西。 例如,如果你正在逐步parsing算术。
- 作为一个身份函数作为parameter passing给一些function。
- 对于符号积累的代数结构 – 阶梯运算符等。 当然,这可以用其他函数来完成,但是可以想象的看到像
y=+++---+++x
这样的东西。 更甚者,他们不必上下class。 这构成了一个免费的可能有用的加号和减号组。 即使在正式的语法实现。 - 野性使用:在某种意义上,它可以将计算中的某个步骤标记为“主动”。 收获/播种系统 – 每一个加号都会记住这个值,最后,你可以收集收集到的中间体……因为为什么不呢?
那加上所有别人提到的types转换的原因。
毕竟,如果您需要更多的操作员,我们感到非常高兴。
__pos__()
存在于Python中 ,为程序员提供与C++
语言相似的可能性 – 重载运算符 ,在这种情况下是一元运算符 +
。
( 重载操作符意味着为不同的对象赋予不同的含义 ,例如, 二进制+
对于数字和string的行为是不同的 – 在串联string时添加数字。
对象可以实现(旁边的)这些仿真数字types函数(方法):
__pos__(self) # called for unary + __neg__(self) # called for unary - __invert__(self) # called for unary ~
所以+object
意味着与object.__pos__()
相同object.__pos__()
– 它们是可以互换的。
不过+object
更容易上眼。
一个特定对象的创build者可以自由地实现这些function,就像他想要的那样 – 正如其他人在他们现实世界的例子中所performance的那样。
而我的贡献 – 作为一个笑话: ++i != +i
在C / C ++ 。