2010-07-09 3 views
46

내가 아는 바로는, 목록에 + op를 쓰려면 두 번째 피연산자가 반복 가능해야합니다. "ha"는 분명합니다.x가 목록이면 x = "ha"가 작동하는 반면 x = x + "ha"는 예외를 throw하는 이유는 무엇입니까?

코드에서

: 목록이 +=를 사용

>>> x = [] 
>>> x += "ha" 
>>> x 
['h', 'a'] 
>>> x = x + "ha" 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: can only concatenate list (not "str") to list 
+1

나는 귀하의 질문에 "동의"합니다. 이것은 나를 위해 연산자 오버로딩에 대한 좋은 논쟁이다. – u0b34a0f6ae

+0

편집 후 내 답변을 삭제했습니다. 목록과 반복 가능 목록 사이에 + 지원하지 않는 이유에 대해 궁금해하는 것 같습니다. 저의 실수입니다. "그래, 왜 안되니?"라고 대답하는 것 외에는 대답이 없습니다. –

+3

이것은 * major * 파손입니다. 보다 일반적으로 동일하게 보이는 운영자에게 다른 행동을 정의하는 언어 또는 라이브러리는 사용자 적대적으로 간주되어야합니다. 문자열 연결에'+'를 사용하는 사람은 아무도 없습니다 : 그 연산은 교환 가능하지 않습니다! –

답변

33

extend하지 +를 호출하는 것과 같습니다.

  • 반복 가능한 코드로 extend을 호출 할 수 있습니다.
  • 다른 목록에는 + 만 사용할 수 있습니다.

나는이 결정이 만들어진 이유를 추측 할 수 있지만 성능상의 이유로 상상할 수 있습니다. +을 호출하면 새로운 개체가 생성되고 모든 항목이 복사되는 반면, extend은 기존 목록 개체의 여유 공간을 사용하여 복사본을 저장하는 경우가 있습니다.

이 결정의 또 다른 부작용은 x += y이라고 쓰면 목록에 다른 참조가 표시되지만, x = x + y을 사용하면 변경되지 않습니다. 이 아래에 설명된다 :

 
>>> x = ['a','b'] 
>>> y = ['c', d'] 
>>> z = x 
>>> x += y 
>>> z 
['a', 'b', 'c', 'd'] 

>>> x = ['a','b'] 
>>> y = ['c', d'] 
>>> z = x 
>>> x = x + y 
>>> z 
['a', 'b'] 

참조

Python source code for list합니다. +=에 대한

소스 코드 :

 
static PyObject * 
list_inplace_concat(PyListObject *self, PyObject *other) 
{ 
    PyObject *result; 

    result = listextend(self, other); 
    if (result == NULL) 
     return result; 
    Py_DECREF(result); 
    Py_INCREF(self); 
    return (PyObject *)self; 
} 

소스 코드 +의 경우 : 거꾸로 그것에 대해 생각하고

 
static PyObject * 
list_concat(PyListObject *a, PyObject *bb) 
{ 
    Py_ssize_t size; 
    Py_ssize_t i; 
    PyObject **src, **dest; 
    PyListObject *np; 
    if (!PyList_Check(bb)) { 
     PyErr_Format(PyExc_TypeError, 
        "can only concatenate list (not \"%.200s\") to list", 
        bb->ob_type->tp_name); 
     return NULL; 
    } 

    // etc ... 
+20

여기 진짜 질문은 "왜 그런 불일치입니까?"라고 생각합니다. – doublep

+0

나는이 질문에 전혀 대답하지 않으므로이 답변에 -1을 갈 것이다. (@ doublep의 설명 참조). –

+5

나는이 질문이 디자인에 대한 비판이라는 것은 분명하지 않다고 생각한다. 첫 번째 단계는 불일치가 어떻게 구현되는지 이해하는 것이고, 이것이 우리가 여기서 도울 수있는 전부입니다. 당신이 저에게 묻는다면 당신이 commenter가 묻는 큰 질문은 완전히 범위의 범위를 벗어났습니다. :) –

8

. x += 'ha'이 작동하는 이유를 x = x + 'ha'이 예외를 던지는 이유를 묻습니다. 정말로, 질문은 x += 'ha'이 전혀 작동하지 않는 이유입니다.

모두 'abc' + 'ha'[1, 2, 3] + ['h', 'a']이 작동해야한다는 데 동의합니다. 그리고 이러한 경우에 +=에 과부하를 걸면 적절한 수정 작업을 수행 할 수 있습니다.

언어 디자이너는 다른 유형을 혼합하기 때문에 [1, 2, 3] + 'ha'을 사용하지 말아야한다고 결정했습니다. 그리고 그것은 합리적인 것처럼 보인다.

그래서 질문에 그들은 x += 'ha'의 경우에 다른 유형을 섞을 것을 결정했습니다. 이 경우, 나는 몇 가지 이유가 상상 :

  • 가 편리 속기 그것은 무슨 분명
  • 의는 일반적으로

(당신은 x에 반복자의 각 항목을 추가) 파이썬은 여러분이 원하는 것을 할 수있게하려고 시도하지만, 모호한 곳에서는 명시 적으로 강요하는 경향이 있습니다.

+2

다른 임시 -1 :'x + = y'는'x'와'y'에 대해'x = x + y'로 정의됩니다. 당신이 질문에 답하는 것을 피했음을 즉시 알 수 있습니다. ;) –

+6

여기에 요점은 분명하지 않다는 것입니다. 따라서 질문입니다. '+ ='와'+'가 모두 정의되는 다른 대부분의 프로그래밍 언어에서,'x + = y'는'x = x + y'와 똑같이 정의됩니다. 실제로 일반적으로 하나는 다른 하나의 별칭입니다. –

+0

당신이 그것을 시도한다면, 그것은 분명히 무슨 일이 일어나는 지 분명합니다. 그리고 그것이 작동하지 않을 것이라면, 실망 할 것입니다. –

5

연산자를 정의 할 때 두 가지 다른 "더하기"연산자가 있습니다. 하나는 __add__이고 다른 하나는 __iadd__입니다. 후자는 +=으로 전체를 추가하는 것이고, 다른 하나는 정규 + 연산자입니다. http://docs.python.org/reference/datamodel.html에 더 많은 정보가 있습니다.