파이썬 : 나만의 연산자 정의?


80

내 자신의 연산자를 정의하고 싶습니다. 파이썬은 그런 것을 지원합니까?


글쎄, 당신은 정의 (같은되지 않은 운영자 가질 수 $) 다음 (과 편집 자체에 약간의 파이썬 코드를 사용합니다 open) 모든 변경 a $ bfunction(a,b)
whackamadoodle3000

답변:


40

아니요, 새 연산자를 만들 수 없습니다. 그러나 표현식 만 평가하는 경우 문자열을 직접 처리하고 새 연산자의 결과를 계산할 수 있습니다.


1
Python의 사전 정의 된 재정의 가능한 연산자 집합은 아래 를 참조하십시오 .
팔리 몬도

179

기술적으로는 파이썬에서 새로운 연산자를 정의 할 수 없지만이 영리한 해킹 은이 제한을 우회합니다. 다음과 같이 중위 연산자를 정의 할 수 있습니다.

# simple multiplication
x=Infix(lambda x,y: x*y)
print 2 |x| 4
# => 8

# class checking
isa=Infix(lambda x,y: x.__class__==y.__class__)
print [1,2,3] |isa| []
print [1,2,3] <<isa>> []
# => True

2
+1 그 해킹은 꽤 멋지지만이 상황에서는 작동하지 않을 것 같습니다.
Zifre

9
흥미로운 해킹 일 수 있지만 이것이 좋은 해결책이라고 생각하지 않습니다. 파이썬은 자신의 연산자를 만드는 것을 허용하지 않습니다. 디자인 결정은 합당한 이유로 만들어 졌으므로 이것을 문제로 간주하고 그에 대한 방법을 발명하는 대신 받아 들여야합니다. 코드를 작성하는 언어에 맞서 싸우는 것은 좋은 생각이 아닙니다. 정말로 원한다면 다른 언어를 사용해야합니다.
DasIch

79
@DasIch 나는 더 이상 동의 할 수 없었다. 우리 모두가 의도적으로 언어를 선택할 자유는 없습니다. 반면에 내가 만족스럽지 않으면 다른 사람의 디자인 결정에 왜 안주해야하는지 모르겠습니다. -정말 훌륭한 해킹!
ThomasH

+1 아주 멋진 해킹에 대해,하지만 내 질문은 내 자신의 연산자를 정의하는 것이 파이썬의 기능인지 아닌지에 대한 것이었고, 새로운 연산자를 가진 가짜가 가능한지 아닌지에 대한 것이었고 대답은 '아니오', 할 수 없습니다 새로운 연산자를 정의합니다. 이것은 꽤 가까이 다가 오지만.
ArtOfWarfare 2014-06-12

2
나는 이것을 pipefrom toolz. pip = Infix(lambda x,y: pipe(x,y)). 그런 다음 8 |pip| range |pip| sum |pip| range. 작동하는 것 같습니다.
cantdutchthis

44

아니요, Python에는 사전 정의되었지만 재정의 가능한 연산자 집합 이 함께 제공됩니다 .


1
나는 방법을 알고 궁금 dfply사용하는 -->운영자 : towardsdatascience.com/...
최대 Candocia

1
@MaxCandocia 내가 말할 수있는 한, 그렇지 않습니다 ( 문서 참조 ). 사용하는 게시물의 예는 -->의사 코드 인 것 같습니다. 라이브러리 자체가 오버로드 >>됩니다.
Andrew Marshall

11

Sage는 기본적으로 @Ayman Hourieh가 설명하는 "영리한 해킹"을 사용하여이 기능을 제공하지만 더 깔끔한 모양과 추가 기능을 제공하기 위해 모듈에 데코레이터로 통합되었습니다. 오버로드 할 연산자를 선택할 수 있으므로 평가 순서를 선택할 수 있습니다.

from sage.misc.decorators import infix_operator

@infix_operator('multiply')
def dot(a,b):
    return a.dot_product(b)
u=vector([1,2,3])
v=vector([5,4,3])
print(u *dot* v)
# => 22

@infix_operator('or')
def plus(x,y):
    return x*y
print(2 |plus| 4)
# => 6

자세한 내용 은 Sage 설명서이 향상된 추적 티켓 을 참조하십시오.


10

특정 객체 클래스에 작업을 적용하려는 경우 함수와 가장 가까운 연산자를 재정의 할 수 있습니다. 예를 들어 __eq__()재정의는 ==연산자를 재정 의하여 원하는 것을 반환합니다. 이것은 거의 모든 운영자에게 적용됩니다.


9

Python 3.5 @에는 추가 연산자에 대한 기호 가 도입되었습니다 .

PEP465 는 많은 숫자 코드의 표기법을 단순화하기 위해 행렬 곱셈을위한이 새로운 연산자를 도입했습니다. 연산자는 모든 유형에 대해 구현되지 않고 배열과 유사한 객체에 대해서만 구현됩니다.

다음을 구현하여 클래스 / 객체에 대한 연산자를 지원할 수 있습니다. __matmul__() .

PEP는 배열과 유사하지 않은 객체에 대해 연산자를 다르게 사용할 수있는 공간을 남깁니다.

물론 @배열과 같은 객체에 대해서도 행렬 곱셈과 다른 모든 종류의 작업으로 구현할 수 있지만 모든 사람이 데이터 유형이 다른 방식으로 작동 할 것으로 기대하기 때문에 사용자 경험에 영향을 미칩니다.


그게 @새로운 연산자 기호 라는 뜻 입니까? 아니면 우리 자신의 새로운 연산자를 정의하는 데 어떻게 든 사용할 수 있습니까?
Addem

예, @은 새로운 연산자 기호입니다. 예, 개체에 대한 작업을 정의하는 데 사용할 수 있습니다. PEP465를 읽어보십시오.
gg349

5
@Addem 그는 단지 그것이 @새로운 연산자 라는 것을 의미했습니다 . 그게 다야. 사실은 여전히 ​​남아 있습니다. Python에서 자신의 연산자를 정의 할 수 없습니다.
존 레드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.