프로그램을 만들다 보면 "="기호를 많이 사용하게 된다. VB에서 =는 2가지 작용을 하는데, 한가지는 양 변에 있는 두 존재를 비교하여 같은지 다른지 판단한 후 참/거짓을 알려준다. 다른 하나는 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다.

C언어에서 =는 1가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다. C언어에서 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.

파이썬에서도 =기호는 두가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어주거나, 오른쪽에 있는 존재를 왼쪽에 있는 존재와 같은 놈으로 만들어 준다. 파이썬에서도 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.

예를들어

a = 1
b = a
a = 11
print(a)
print(b)

이런 프로그램을 실행시키면 파이썬의 출력은
11
1
이 된다. 즉, 이 경우에는 변수 a의 값이 변수 b로 복사되고, a와 b는 아무 관련 없는 모르는 사이가 되었다. a를 바꾸더라도 b는 변하지 않는다.

그런데
a = [10,20]
b = a
a[1]=11
print(a)
print(b)
위와 같은 프로그램을 실행시키면 출력은
[10, 11]
[10, 11]
이 된다. 이 경우에는, a와 b가 완전히 같은 존재가 되어 a를 바꾸면 b도 바뀌게 된다. 만약 a를 b로 복사해서 넣고 싶다면 copy 모듈을 불러와야 한다.

import copy
a = [10,20]
b = copy.copy(a)
a[1]=11
print(a)
print(b)
이렇게 하면 b는 a의 내용을 복사해서 받은 존재가 되어 a가 변해도 b는 변하지 않는다. (반대도 마찬가지) 따라서 이 프로그램의 출력은 다음과 같다.
[10, 11]
[10, 20]

아무튼. 직관적인 내용이므로 알면 편한데 문서 대충 읽고 개발하는 내게는 충격적이었다. 이게 왜 바뀌지? 싶은거...

물론 이런식으로 존재 자체에 대한 =연산자는 VB나 C/C++에는 없다. 별다른 생각 없이 직관적으로 =연산자를 사용해서 존재에 존재를 연관시키는 것이 장점이긴 한데, 존재의 종류에 따라 작동이 달라지는 것은 일관적이지는 않은 행동인것 같다. (물론, +연산자도 문자열 변수와 수치형 변수에 대해 다르게 작동하며 이것도 일관적인 행동은 아니다. 다만 직관적인 행동이다.)


신고
by snowall 2011.07.06 01:51
  • solariser 2011.07.06 03:00 신고 ADDR EDIT/DEL REPLY

    우와~ 스럽네요.. -_-

    1. 존재라는 표현은 잘못 된 것입니다. 존재면 being인가요? 존재라는 표현자체가 적어도 C, C++, Perl, Python, Java, VB, Javascript에는 없습니다.

    2. smalktalk이후로 절대 다수의 프로그래밍 언어는 Python과 동일하게 동작합니다. Primitive Type이 아닐경우 Reference로 전달되는 것이 당연합니다. (왜 그런지는 구글링을 해보아요)

    3. C++은 SmalTalk이전의 언어이고, GC가 없기 때문에, = 연산이 memcopy와 동일합니다. 따라서 깊은 복사, 얕은 복사의 개념의 존재하게 됩니다. (물론 복사의 종류는 Python에도 동일하게 적용됩니다. 이건 논리적인 부분이라서) 또한 C++의 Class를 디자인 하는 방식에 따라서는 얕은 복사에 의해서 결과적으로 Referenc만 받는 것과 동일한 결과가 발생할 수 있습니다. 결과적으로 C++의 방식이 더 복잡하며, 프로그래머가 고려해야되는 요소가 너무 많아지는 단점이 있으며, 동작이 일관되지 못하는 단점이 있습니다. (해당 내용은 C++ 복사 생성자 같은걸로 검색하면 찾을수 있습니다. 물론 이러한 생성자 오버로딩도 설계를 잘한다는 전재로 볼때는 C++의 장점이 됩니다. 다만.... 그걸 고려하는 사람을 찾기가 더 힘든 세상이지요...)

    4. C++에서는 레퍼런스를 사용해서 인스턴스를 직접 엑서스 할 수 있습니다.
    int a = 10;
    int &b = a;
    a = 1;
    assert(a == b == 1);
    이렇게 됩니다.
    (물론 내부적으로 포인터... 이긴 합니다. 사실은 훼이크지만, 그래도 좋은 기능이긴 합니다.)

    5. 연산자의 동작은 항상 일관 됩니다. Python을 예로 들면 + 는 해당 Type(클래스)의 항상 __add__ 메쏘드가 호출됩니다. Python은 모든 것이 객체 이기 때문에, 모든 연산이 저렇게 구현되어 있고, 단하나의 예외도 없습니다.

    • snowall 2011.07.06 08:14 신고 EDIT/DEL

      1. 제가 만든 단어예요
      2. 네...
      3. 그렇군요...
      4. 물론 그렇죠.
      5. 파이썬을 어떻게 구현했는가는 제 관심 대상이 아닙니다.

      음... 그냥 대충 배워서 대충 쓰고 싶은데 그렇게 깊이있게 알아야 하나요?

    • lemma 2011.07.07 00:40 신고 EDIT/DEL

      php 같은 경우는 = 사용시에 array 도 복사되기 때문에 snowall 님 의도대로 동작합니다.
      얕은 복사가 당연한 것은 아닙니다. 단지 효율성이나 구현등의 문제겠죠.

    • snowall 2011.07.07 00:47 신고 EDIT/DEL

      PHP는 또 다른 구현을 갖고 있군요

      네트의 세계는 역시 광대하네요 -_-

    • loveing 2012.05.25 15:06 신고 EDIT/DEL

      존재라는 표현 맘에 드는데요 전?

      의미를 이해하는 게 중요한거 아닌가요?

      자신의 지식을 뽐내고 싶어서 트집잡는 거 같네요

    • snowall 2012.05.25 15:21 신고 EDIT/DEL

      감사합니다 ㅎㅎ

  • Lex 2011.07.06 14:10 신고 ADDR EDIT/DEL REPLY

    포인터개념이 기본으로 밖혀 있군요.
    C를 사용하는 저로서는 파격적이네요. ^^;;
    그리고, 위의 기자분 전화번호를 남발하셔도 되는지... 심히 걱정되네요. ^^;;;;

    • snowall 2011.07.06 16:55 신고 EDIT/DEL

      그래서 연락드리고 지웠습니다.

      VB를 쓰던 저로서도 파격적이긴 해요. VB에는... 한숨만 나오는 언어죠.

  • goldenbug 2011.07.06 16:05 신고 ADDR EDIT/DEL REPLY

    그러게요.. 기자분...좀 위험해 보이네요. ^^;