一般来说,一元+人在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)
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是+infinity和1/-epsilon= -infinity.这是嘴皮子的限制更1/x是xaproaches 0从右边(+)或从左侧( - ).
作为0和+0表现不同,它是有道理的0 != +0.
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)
对于对称性,因为一元减号是一个算子,一元加号也必须是.在大多数算术情况下,它没有做任何事情,但请记住,用户可以定义任意类并将这些运算符用于他们想要的任何内容,即使它不是严格的代数.
我知道这是一个旧线程,但我想扩展现有的答案以提供更广泛的示例:
+ 如果不是 - 可以断言积极性并抛出异常 - 检测极端情况非常有用.±sqrt(z)为单个对象 - 用于求解二次方程,对于多分支分析函数,任何可以将二值函数"折叠"到带有符号的一个分支中的任何东西.这包括vlopez提到的±0情况.y=+++---+++x.更重要的是,他们不必通勤.这构建了一个免费的正和负组,这可能是有用的.甚至在正式的语法实现中.那,加上其他人提到的所有类型转换的原因.
毕竟...如果你需要的话,还有一个操作员很高兴.
__pos__()Python中的存在为程序员提供了与\xe2\x80\x94C++语言中类似的可能性来重载运算符,在本例中为一元运算符 +。
(重载运算符意味着为不同的对象赋予它们不同的含义,例如,二进制对于+数字和字符串的行为不同, \xe2\x80\x94在连接字符串时添加数字。)
对象可以实现(除了其他之外)这些模拟数字类型函数(方法):
\n\n __pos__(self) # called for unary +\n __neg__(self) # called for unary -\n __invert__(self) # called for unary ~\nRun Code Online (Sandbox Code Playgroud)\n\n因此+object与 \xe2\x80\x94 的含义相同,object.__pos__()它们是可以互换的。
不过,+object比较养眼。
特定对象的创建者可以自由地实现这些功能,因为他想要 \xe2\x80\x94 正如其他人在现实世界的示例中所展示的那样。
\n\n我的贡献 \xe2\x80\x94作为一个笑话: ++i != +i 在 C/C++ 中。
这里的很多例子看起来更像是错误。不过,这实际上是一个功能:
+运营商意味着一个副本。这在为标量和数组编写通用代码时非常有用。
例如:
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......我想那会奏效,但它很麻烦。
一元+是一个非常好的选择。
| 归档时间: |
|
| 查看次数: |
10372 次 |
| 最近记录: |