파이썬에서 + (pos) 단항 연산자의 목적은 무엇입니까?
일반적으로 +
파이썬 에서 단항 은 무엇을해야 합니까?
지금까지 다음과 같은 상황을 본 적이 없기 때문에 묻습니다.
+obj != obj
어디 obj
일반 객체가 구현됩니다 __pos__()
.
그래서 궁금합니다. 왜 존재 +
하고 __pos__()
존재합니까? 위의 표현식이로 평가되는 실제 예제를 제공 할 수 있습니까 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')
저는 C에서 영감을 얻은 Python 연산자를 믿습니다. 여기서 +
연산자는 대칭을 위해 도입되었습니다 (또한 유용한 해킹, 주석 참조).
PHP 또는 Javascript와 같이 약한 유형의 언어에서 +는 런타임에 변수 값을 숫자로 강제 변환하도록 지시합니다. 예를 들어, Javascript에서 :
+"2" + 1
=> 3
"2" + 1
=> '21'
Python은 강력한 형식이므로 문자열은 숫자로 작동하지 않으므로 단항 더하기 연산자를 구현하지 않습니다.
+ obj! = obj 인 객체를 구현하는 것은 확실히 가능합니다.
>>> class Foo(object):
... def __pos__(self):
... return "bar"
...
>>> +Foo()
'bar'
>>> obj = Foo()
>>> +"a"
실제로 의미가있는 예는 초현실적 인 숫자를 확인하세요 . 그것들은 극소값 (+ 엡실론,-엡실론)을 포함하는 실수의 상위 집합입니다. 여기서 엡실론은 다른 양수보다 작지만 0보다 큰 양의 값입니다. 무한대 (+ 무한대,-무한대).
epsilon = +0
, 및을 정의 할 수 -epsilon = -0
있습니다.
하지만 1/0
아직 정의되지, 1/epsilon = 1/+0
이다 +infinity
, 그리고 1/-epsilon
= -infinity
. 그것은 오른쪽 (+) 또는 왼쪽 (-)에서 비정상적으로 제한하는 1/x
것에 지나지 않습니다 .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})
따라서에서 음수 또는 0 카운트가 Counter
있으면 +obj != obj
.
>>> obj = Counter({'a': 0})
>>> +obj != obj
True
대칭의 경우 단항 마이너스가 연산자이므로 단항 플러스도 마찬가지 여야합니다. 대부분의 산술 상황에서 아무 작업도 수행하지 않지만 사용자는 임의의 클래스를 정의하고 엄격하게 대수적이지 않더라도 원하는 모든 작업에 이러한 연산자를 사용할 수 있습니다.
나는 그것이 오래된 스레드라는 것을 알고 있지만 더 광범위한 예제를 제공하기 위해 기존 답변을 확장하고 싶었습니다.
+
긍정 성을 주장하고 그렇지 않은 경우 예외를 던질 수 있습니다. 코너 케이스를 감지하는 데 매우 유용합니다.- The object may be multivalued (think
±sqrt(z)
as a single object -- for solving quadratic equations, for multibranched analytical functions, anything where you can "collapse" a twovalued function into one branch with a sign. This includes the ±0 case mentioned by vlopez. - If you do lazy evaluation, this may create a function object that adds something to whatever it is applied to something else. For instance, if you are parsing arithmetics incrementally.
- As an identity function to pass as an argument to some functional.
- For algebraic structures where sign accumulates -- ladder operators and such. Sure, it could be done with other functions, but one could conceivably see something like
y=+++---+++x
. Even more, they don't have to commute. This constructs a free group of plus and minuses which could be useful. Even in formal grammar implementations. - Wild usage: it could "mark" a step in the calculation as "active" in some sense. reap/sow system -- every plus remembers the value and at the end, you can gather the collected intermediates... because why not?
That, plus all the typecasting reasons mentioned by others.
And after all... it's nice to have one more operator in case you need it.
A lot of examples here look more like bugs. This one is actually a feature, though:
The +
operator implies a copy.
This is extremely useful when writing generic code for scalars and arrays.
For example:
def f(x, y):
z = +x
z += y
return z
This function works on both scalars and NumPy arrays without making extra copies and without changing the type of the object and without requiring any external dependencies!
If you used numpy.positive
or something like that, you would introduce a NumPy dependency, and you would force numbers to NumPy types, which can be undesired by the caller.
If you did z = x + y
, your result would no longer necessarily be the same type as x
. In many cases that's fine, but when it's not, it's not an option.
If you did z = --x
, you would create an unnecessary copy, which is slow.
If you did z = 1 * x
, you'd perform an unnecessary multiplication, which is also slow.
If you did copy.copy
... I guess that'd work, but it's pretty cumbersome.
Unary +
is a really great option for this.
__pos__()
exists in Python to give programmers similar possibilities as in C++
language - to overload operators, in this case the unary operator +
.
(Overloading operators means give them a different meaning for different objects, e . g. binary +
behaves differently for numbers and for strings - numbers are added while strings are concatenated.)
Objects may implement (beside others) these emulating numeric types functions (methods):
__pos__(self) # called for unary +
__neg__(self) # called for unary -
__invert__(self) # called for unary ~
So +object
means the same as object.__pos__()
- they are interchangeable.
However +object
is more easy on the eye.
Creator of a particular object has free hands to implement these functions as he wants - as other people showed in their real world's examples.
And my contribution - as a joke: ++i != +i
in C/C++.
참조 URL : https://stackoverflow.com/questions/16819023/whats-the-purpose-of-the-pos-unary-operator-in-python
'programing' 카테고리의 다른 글
R에서 x 축 눈금으로 플로팅 할 실제 x 축 값을 지정하는 방법 (0) | 2021.01.14 |
---|---|
두 변수에 동일한 참조가 있는지 확인하는 방법은 무엇입니까? (0) | 2021.01.14 |
PyCharm에 대한 변수 탐색기가 있습니까? (0) | 2021.01.14 |
Swift의 매크로? (0) | 2021.01.14 |
지역 변수 범위에 문제가 있습니다. (0) | 2021.01.14 |