development

파이썬에 왜 ++와-연산자가 없는가?

big-blog 2020. 2. 19. 22:03
반응형

파이썬에 왜 ++와-연산자가 없는가?


왜이없는 ++--파이썬에서 연산자는?


이해가되지 않기 때문이 아닙니다. "x ++"를 "x + = 1로 정의하여 x의 이전 바인딩으로 평가"하는 것이 좋습니다.

원래의 이유를 알고 싶다면 오래된 파이썬 메일 링리스트를 살펴 보거나 거기에 있던 누군가에게 물어봐야합니다 (예 : 귀도). 그러나 사실 이후 정당화하기는 쉽습니다.

다른 언어만큼 간단한 증감이 필요하지 않습니다. for(int i = 0; i < 10; ++i)파이썬 과 같은 것을 자주 쓰지 않습니다 . 대신 당신은 같은 일을 for i in range(0, 10)합니다.

거의 자주 필요하지 않기 때문에 고유 한 구문을 제공 할 이유가 훨씬 적습니다. 증분해야 할 때 +=일반적으로 괜찮습니다.

그것이 말이되는지, 할 수 있는지, 할 수 있는지의 여부에 대한 결정이 아닙니다. 이점이 언어의 핵심 구문에 추가 할 가치가 있는지에 대한 질문입니다. 이것은 postinc, postdec, preinc, predec의 네 가지 연산자이며 각각의 클래스 오버로드가 필요합니다. 그것들은 모두 명시되고 테스트되어야한다. 언어에 opcode를 추가합니다 (더 큰 VM 엔진을 의미 함). 논리적 증가를 지원하는 모든 클래스는 (위에이를 구현해야 +=하고 -=).

이 모두와 +=중복 -=되므로 순손실이됩니다.


내가 쓴이 원래의 대답은 컴퓨팅의 민속에서 신화 : 편집자의 편지에서 언급 한 바와 같이 "역사적으로 불가능"으로 데니스 리치에 의해 정체를 폭로 ACM의 통신 2012년 7월 10.1145 / 2209249.2209251 : 도이


C 증분 / 감소 연산자는 C 컴파일러가 똑똑하지 않은 시점에 발명되었으며 저자는 기계 언어 연산자를 사용해야하는 직접적인 의도를 지정할 수 있기를 원했습니다. 할 수 있습니다

load memory
load 1
add
store memory

대신에

inc memory 

PDP-11 은 각각 *++p및에 해당하는 "자동 증가"및 "자동 증가 지연"명령도 지원 *p++했습니다. 몹시 호기심이 많으면 매뉴얼 5.3 절을 참조하십시오 .

컴파일러는 C 구문에 내장 된 고급 최적화 트릭을 처리 할 수있을만큼 똑똑하기 때문에 지금은 구문상의 편의에 불과합니다.

파이썬에는 의도를 사용하지 않기 때문에 의도를 어셈블러에 전달하는 트릭이 없습니다.


나는 항상 파이썬의이 선과 관련이 있다고 가정했습니다.

이를 수행 할 수있는 확실한 방법이 하나 있어야합니다.

x ++와 x + = 1은 똑같은 작업을 수행하므로 둘 다 가질 이유가 없습니다.


물론 우리는 "Guido가 그렇게 결정했다"고 말할 수 있지만, 그 결정의 이유에 대한 질문이라고 생각합니다. 몇 가지 이유가 있다고 생각합니다.

  • 문장과 표현을 혼합하여 사용하는 것은 좋지 않습니다. http://norvig.com/python-iaq.html 참조
  • 일반적으로 사람들이 읽기 어려운 코드를 작성하도록 권장합니다.
  • 이미 언급했듯이 파이썬에서는 필요하지 않은 언어 구현의 추가 복잡성

파이썬에서 정수는 불변이기 때문에 (int의 + =는 실제로 다른 객체를 반환합니다).

또한 ++ /-를 사용하면 사전 및 사후 증분 / 감소에 대해 걱정할 필요가 있으며 키를 한 번 더 입력하면 x+=1됩니다. 다시 말해, 이득이 거의 없어도 혼동을 피할 수 있습니다.


명쾌함!

파이썬은 명확성 에 대해 많은 것이 있으며, --a그 구조를 가진 언어를 배우지 않으면 프로그래머가 그 의미를 정확하게 추측하지 못할 것 입니다.

파이썬은 또한에 대해 많은입니다 실수를 초대 구조 피++운영자가 결함의 풍부한 소스 것으로 알려져됩니다. 이 두 가지 이유는 파이썬에서 그 연산자를 갖기에 충분하지 않습니다.

파이썬이 들여 쓰기를 사용하여 시작 / 종료 브라케팅 또는 필수 끝 표시와 같은 구문 적 수단보다는 블록을 표시한다는 결정은 대체로 동일한 고려 사항을 기반으로합니다.

예를 들어, 2005 년 조건부 연산자 (C cond ? resultif : resultelse:)를 Python에 도입하는 것에 관한 토론을 살펴 보십시오. 적어도 해당 토론첫 번째 메시지결정 메시지 (이전에 동일한 주제에 대해 여러 개의 선구자가 있음 )를 읽으십시오 .

퀴즈 : 자주 언급되는 PEP는 "Python Extension Proposal" PEP 308 입니다. LC는 list comprehension을 의미 하고 GE는 generator expression을 의미 합니다 (그리고 혼동하더라도 걱정할 필요가 없습니다. 파이썬의 복잡한 부분은 아닙니다).


그것은 단지 그런 식으로 설계되었습니다. 증가 및 감소 연산자는 바로 가기입니다 x = x + 1. 파이썬은 일반적으로 작업을 수행하는 대체 수단의 수를 줄이는 설계 전략을 채택했습니다. 확장 할당 은 파이썬에서 연산자를 증가 / 감소시키는 가장 가까운 것이며, 파이썬 2.0까지 추가되지 않았습니다.


파이썬에 ++연산자가 없는 이유에 대한 나의 이해 는 다음과 같습니다. 파이썬으로 이것을 작성할 때 a=b=c=1동일한 객체 (값 1)를 가리키는 세 개의 변수 (라벨)가 나타납니다. 객체 메모리 주소를 반환하는 id 함수를 사용하여이를 확인할 수 있습니다.

In [19]: id(a)
Out[19]: 34019256

In [20]: id(b)
Out[20]: 34019256

In [21]: id(c)
Out[21]: 34019256

세 가지 변수 (라벨)는 모두 같은 객체를 가리 킵니다. 이제 변수 중 하나를 증가시키고 그것이 메모리 주소에 어떻게 영향을 미치는지보십시오 :

In [22] a = a + 1

In [23]: id(a)
Out[23]: 34019232

In [24]: id(b)
Out[24]: 34019256

In [25]: id(c)
Out[25]: 34019256

a변수가 변수 b로 다른 객체를 가리키는 것을 볼 수 있습니다 c. 당신이 a = a + 1그것을 사용했기 때문에 분명히 분명합니다. 즉, label에 완전히 다른 객체를 할당합니다 a. a++변수 a새 객체에 할당하지 않고 오래된 객체를 래터 증가 시킨다는 것을 제안 할 수 있다고 상상해보십시오 . 이 모든 것은 혼란을 최소화하기위한 IMHO입니다. 더 잘 이해하려면 파이썬 변수의 작동 방식을 참조하십시오.

파이썬에서 함수가 호출자가 인식 한 일부 인수를 수정할 수 있지만 다른 인수는 수정할 수없는 이유는 무엇입니까?

파이썬은 값에 의한 호출입니까, 아니면 참조에 의한 호출입니까? 둘 다.

파이썬은 가치 또는 참조로 전달합니까?

파이썬은 참조에 의한 전달입니까, 값에 의한 전달입니까?

파이썬 : 참조로 변수를 전달하는 방법은 무엇입니까?

파이썬 변수와 메모리 관리 이해

파이썬에서 가치에 따른 행동 모방

파이썬 함수는 참조로 호출

Pythonista와 같은 코드 : 관용적 파이썬


나는 파이썬을 처음 접했지만 그 이유는 언어 내에서 변경 가능한 객체와 변경 불가능한 객체 사이의 강조 때문이라고 생각합니다. 이제 x ++을 x = x + 1로 쉽게 해석 할 수 있다는 것을 알고 있지만 변경할 수없는 객체를 제자리에서 늘리는 것처럼 보입니다 .

내 추측 / 느낌 / 직감.


첫째, 파이썬은 C에 의해서만 간접적으로 영향을받습니다. ABC에 크게 영향을받으며 , 이러한 연산자 는없는 것 같습니다. 따라서 파이썬에서도 찾을 수 없다는 것은 놀라운 일이 아닙니다.

다른 사람이 말했듯이 두 번째로, 증가 및 감소에 의해 지원 +=-=이미.

셋째, ++--연산자 집합에 대한 완벽한 지원 에는 일반적으로 접두사 및 접미사 버전을 모두 지원하는 것이 포함됩니다. C와 C ++에서 이것은 모든 종류의 "사랑스러운"구성체가 파이썬이 받아들이는 단순성과 직설 성의 정신에 위배되는 것처럼 보일 수 있습니다.

예를 들어, C 문 while(*t++ = *s++);은 숙련 된 프로그래머, 그것을 배우는 사람에게는 단순하고 우아하게 보일 수 있지만 간단합니다. 접두사와 접두사 증가 및 감소를 혼합하여 던져보십시오. 심지어 많은 전문가들도 그만두고 조금 생각해야합니다.


나는 그것이 "명시적인 것이 묵시적인 것보다 낫다"는 파이썬 신조에서 나온 것이라고 믿는다.


@GlennMaynard 가 다른 언어와 비교하여 문제를보고 있기 때문일있지만 파이썬에서는 파이썬 방식으로 일을합니다. '왜'질문이 아닙니다. 거기에 있으며와 같은 효과를 낼 수 있습니다 x+=. 에서 파이썬의 선 , 주어진 : "만 문제를 해결하는 하나 개의 방법이 있어야한다." 객관식은 예술 (표현의 자유)에서는 훌륭하지만 공학에서는 까다 롭습니다.


++사업자의 클래스는 부작용 표현입니다. 이것은 일반적으로 파이썬에서 찾을 수없는 것입니다.

같은 이유로 할당은 파이썬에서 표현식이 아니므로 일반적인 if (a = f(...)) { /* using a here */ }관용구를 막습니다.

마지막으로 연산자가 파이썬 참조 의미와 매우 일치하지 않는다고 생각합니다. 파이썬에는 C / C ++에서 알려진 의미론을 가진 변수 (또는 포인터)가 없습니다.


이 연산자가 왜 C에 존재하는지 묻는 것이 더 좋은 질문 일 것입니다. 서론은 그것들을 '더 간결하고 종종 더 효율적'이라고 부릅니다. 이러한 조작이 항상 포인터 조작에서 발생한다는 사실이 도입에 일부 영향을 미쳤다고 생각합니다. 파이썬에서는 증분 최적화를 시도하는 것이 타당하지 않다고 결정되었을 것입니다 (사실 C에서 테스트를 수행했으며 gcc 생성 어셈블리는 두 경우를 모두 포함하지 않고 addl을 사용하는 것 같습니다) 포인터 산술; 그래서 그것은 한 가지 더 할 수있는 방법 일 것입니다. 우리는 파이썬이 그것을 싫어한다는 것을 알고 있습니다.


내가 이해 했으므로 메모리의 값이 변경되지 않았다고 생각합니다. x ++를 수행하면 c에서 메모리의 x 값이 변경됩니다. 그러나 파이썬에서는 모든 숫자를 변경할 수 없으므로 x가 x로 지정한 x의 주소는 x + 1이 아닙니다. x ++를 작성할 때 x가 실제로 발생하는 것은 x refrence가 x + 1이 저장된 메모리의 위치로 변경되거나 존재하지 않는 경우이 위치를 다시 만드는 것입니다.


해당 페이지에서 이미 좋은 답변을 완성하려면 :

++i단항 + 및-연산자를 손상시키는 접두사 ( )를 사용 하기로 결정했다고 가정 해 봅시다 .

오늘날에 의해 접두사 ++또는 --두 번이 단항 플러스 연산자를 수 있기 때문에, 아무것도하지 않는 두 번이나 단항 마이너스 (아무것도하지 않는다) (2 회 : 자체를 취소)

>>> i=12
>>> ++i
12
>>> --i
12

그래서 그것은 아마도 그 논리를 깨뜨릴 것입니다.


나는 이것이 객체의 가변성과 불변성의 개념과 관련이 있다고 생각합니다. 2,3,4,5는 파이썬에서 불변입니다. 아래 이미지를 참조하십시오. 이 파이썬 프로세스까지 2는 고정 ID입니다.

상수 및 변수의 ID

x ++는 본질적으로 C와 같은 인플레 이스 증분을 의미합니다. C에서 x ++는 인플레 이스 증분을 수행합니다. 따라서 3은 여전히 ​​메모리에 존재하는 파이썬과 달리 x = 3이고 x ++는 메모리에서 3을 4로 증가시킵니다.

따라서 파이썬에서는 메모리에 값을 다시 만들 필요가 없습니다. 이것은 성능 최적화로 이어질 수 있습니다.

이것은 직감 기반의 답변입니다.


나는 이것이 오래된 스레드라는 것을 알고 있지만 ++ i의 가장 일반적인 유스 케이스는 다루지 않았으며 제공된 인덱스가 없을 때 수동으로 세트를 색인화합니다. 이 상황에서 파이썬은 enumerate ()를 제공합니다

예 : 어떤 언어로든 foreach와 같은 구문을 사용하여 집합을 반복 할 때-예제를 위해 순서가 지정되지 않은 집합이라고 말하고 모든 것을 구별하기 위해 고유 한 색인이 필요합니다.

i = 0
stuff = {'a': 'b', 'c': 'd', 'e': 'f'}
uniquestuff = {}
for key, val in stuff.items() :
  uniquestuff[key] = '{0}{1}'.format(val, i)
  i += 1

이 경우 파이썬은 열거 방법을 제공합니다.

for i, (key, val) in enumerate(stuff.items()) :

다른 답변은 반복기에 필요하지 않은 이유를 설명했지만 때로는 변수를 인라인으로 늘리도록 할당 할 때 유용합니다. 튜플과 여러 할당을 사용하여 동일한 효과를 얻을 수 있습니다.

b = ++a 된다 :

a,b = (a+1,a+1)

그리고 b = a++된다 :

a,b = a+1, a

파이썬 3.8은 할당 소개하고 :=우리가 달성 할 수 있도록, 운영자 foo(++a)와 함께

foo(a:=a+1)

foo(a++) 그래도 여전히 애매합니다.

참고 URL : https://stackoverflow.com/questions/3654830/why-are-there-no-and-operators-in-python



반응형