Python中+(pos)一元运算符的用途是什么?

use*_*538 54 python

一般来说,一元+人在Python中应该怎么做?

我问,因为到目前为止,我从未见过这样的情况:

+obj != obj
Run Code Online (Sandbox Code Playgroud)

obj通用对象在哪里实现__pos__().

所以我想知道:为什么+__pos__()存在?你能提供一个真实世界的例子,其中上面的表达式评估为True

Chr*_*lor 39

这是包中的"真实世界"示例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')
Run Code Online (Sandbox Code Playgroud)

  • 我不是荷兰人,但这似乎是一种明显的正确方法,可以回复到任何人的正常精确度吗? (29认同)
  • @kojiro:[是](http://stackoverflow.com/a/347749/4279).原因是小数是不可变的,因此可以携带比当前精度更多的数字,以便考虑当前上下文,你需要一个使用它的显式操作,并可能返回一个新的小数,例如,`0 + obj`,` 1*obj`,`obj**1`等等btw,`localcontext()`上面是不必要的:[`+ Decimal('3.1415926535897932384626433832795028841971')`](http://ideone.com/Og4Brl)创建2位小数(1st对应于给定的字符串,2nd对应于当前的精度(结果)). (6认同)
  • 看起来十进制包中的错误比什么都重要。 (5认同)
  • 十进制算术的标准规范指定了表现出这种行为的`plus`和`minus`函数.除了将这些函数作为上下文的一部分提供之外,Python还将它们的行为映射到一元`-`和`+`.请参阅http://speleotrove.com/decimal/daops.html#refplusmin (4认同)

vlo*_*pez 22

我相信Python运营商受C的启发,其中+运算符是为了对称而引入的(还有一些有用的黑客,请参阅注释).

在弱类型语言(如PHP或Javascript)中,+告诉运行时将变量的值强制转换为数字.例如,在Javascript中:

   +"2" + 1
=> 3
   "2" + 1
=> '21'
Run Code Online (Sandbox Code Playgroud)

Python是强类型的,因此字符串不能用作数字,因此,不要实现一元加运算符.

当然可以实现+ obj!= obj的对象:

>>> class Foo(object):
...     def __pos__(self):
...        return "bar"
... 
>>> +Foo()
'bar'
>>> obj = Foo()
>>> +"a"
Run Code Online (Sandbox Code Playgroud)

至于它实际上有意义的例子,请查看 超现实数字.它们是实数的超集,包括无穷小值(+ epsilon, - epsilon),其中epsilon是一个正值,小于任何其他正数,但大于0; 和无限的(+无穷大, - 无穷大).

你可以定义epsilon = +0,和-epsilon = -0.

虽然1/0仍然是不确定的,1/epsilon = 1/+0+infinity1/-epsilon= -infinity.这是嘴皮子的限制更1/xxaproaches 0从右边(+)或从左侧( - ).

作为0+0表现不同,它是有道理的0 != +0.

  • 实际上,在C中,一元"+"具有超越对称性的用途.它不会更改值,但它的存在会强制在算术上发生隐式转换(可能会更改类型). (3认同)

flo*_*ake 19

在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})
Run Code Online (Sandbox Code Playgroud)

因此,如果a中有负数或零计数,则表明存在Counter这样的情况+obj != obj.

>>> obj = Counter({'a': 0})
>>> +obj != obj
True
Run Code Online (Sandbox Code Playgroud)

  • 类似于`-fruits`(它给`Counter({'oranges':89})`). (5认同)

ori*_*ion 5

对于对称性,因为一元减号是一个算子,一元加号也必须是.在大多数算术情况下,它没有做任何事情,但请记住,用户可以定义任意类并将这些运算符用于他们想要的任何内容,即使它不是严格的代数.

我知道这是一个旧线程,但我想扩展现有的答案以提供更广泛的示例:

  • + 如果不是 - 可以断言积极性并抛出异常 - 检测极端情况非常有用.
  • 该对象可以是多值的(想象±sqrt(z)为单个对象 - 用于求解二次方程,对于多分支分析函数,任何可以将二值函数"折叠"到带有符号的一个分支中的任何东西.这包括vlopez提到的±0情况.
  • 如果你进行延迟评估,这可能会创建一个函数对象,它可以将某些内容添加到应用于其他内容的任何内容中.例如,如果您正在逐步解析算术.
  • 作为一个身份函数作为参数传递给某些功能.
  • 对于符号累积的代数结构 - 梯形算子等.当然,它可以通过其他功能来完成,但可以想象会有类似的东西y=+++---+++x.更重要的是,他们不必通勤.这构建了一个免费的正和负组,这可能是有用的.甚至在正式的语法实现中.
  • 狂野使用:在某种意义上,它可以将计算中的一个步骤"标记为""活跃".收获/播种系统 - 每个加号记住价值,最后,你可以收集收集的中间体......因为为什么不呢?

那,加上其他人提到的所有类型转换的原因.

毕竟...如果你需要的话,还有一个操作员很高兴.


Mar*_*anD 5

__pos__()Python中的存在为程序员提供了与\xe2\x80\x94C++语言中类似的可能性来重载运算符,在本例中为一元运算符 +

\n\n

重载运算符意味着为不同的对象赋予它们不同的含义,例如,二进制对于+数字字符串的行为不同, \xe2\x80\x94在连接字符串时添加数字。)

\n\n

对象可以实现(除了其他之外)这些模拟数字类型函数(方法):

\n\n
    __pos__(self)             # called for unary +\n    __neg__(self)             # called for unary -\n    __invert__(self)          # called for unary ~\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此+object与 \xe2\x80\x94 的含义相同,object.__pos__()它们是可以互换的。

\n\n

不过,+object比较养眼。

\n\n

特定对象的创建者可以自由地实现这些功能,因为他想要 \xe2\x80\x94 正如其他人在现实世界的示例中所展示的那样。

\n\n

我的贡献 \xe2\x80\x94作为一个笑话: ++i != +i 在 C/C++ 中

\n

  • `__pos__` 存在是因为 `+` 存在;这并不能解释为什么“+”首先存在。 (3认同)

Meh*_*dad 5

这里的很多例子看起来更像是错误。不过,这实际上是一个功能:

+运营商意味着一个副本

这在为标量和数组编写通用代码时非常有用。

例如:

def f(x, y):
    z = +x
    z += y
    return z
Run Code Online (Sandbox Code Playgroud)

该功能在工作标量NumPy的阵列,而不进行额外的副本并没有改变对象的类型,而不需要任何外部依赖!

如果您使用numpy.positive或类似的东西,您将引入 NumPy 依赖项,并且您将强制数字为 NumPy 类型,这可能是调用者不希望的。

如果您这样做了z = x + y,您的结果将不再与x. 在许多情况下这很好,但如果不是,则不是一种选择。

如果你这样做了z = --x,你会创建一个不必要的副本,这很慢。

如果你这样做了z = 1 * x,你会执行一个不必要的乘法,这也很慢。

如果你这样做了copy.copy......我想那会奏效,但它很麻烦。

一元+是一个非常好的选择。

  • 也许对*你*来说这意味着一份副本。“应该”这一点并不明显,而且人们最常尝试复制的东西肯定不支持它:列表、字典、集合等。 (3认同)