글
프로그램을 만들다 보면 "="기호를 많이 사용하게 된다. VB에서 =는 2가지 작용을 하는데, 한가지는 양 변에 있는 두 존재를 비교하여 같은지 다른지 판단한 후 참/거짓을 알려준다. 다른 하나는 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다.
C언어에서 =는 1가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다. C언어에서 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.
파이썬에서도 =기호는 두가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어주거나, 오른쪽에 있는 존재를 왼쪽에 있는 존재와 같은 놈으로 만들어 준다. 파이썬에서도 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.
예를들어
이런 프로그램을 실행시키면 파이썬의 출력은
그런데
아무튼. 직관적인 내용이므로 알면 편한데 문서 대충 읽고 개발하는 내게는 충격적이었다. 이게 왜 바뀌지? 싶은거...
물론 이런식으로 존재 자체에 대한 =연산자는 VB나 C/C++에는 없다. 별다른 생각 없이 직관적으로 =연산자를 사용해서 존재에 존재를 연관시키는 것이 장점이긴 한데, 존재의 종류에 따라 작동이 달라지는 것은 일관적이지는 않은 행동인것 같다. (물론, +연산자도 문자열 변수와 수치형 변수에 대해 다르게 작동하며 이것도 일관적인 행동은 아니다. 다만 직관적인 행동이다.)
C언어에서 =는 1가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어준다. C언어에서 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.
파이썬에서도 =기호는 두가지 작용을 한다. 오른쪽에 있는 존재의 값을 왼쪽에 있는 존재에게 넣어주거나, 오른쪽에 있는 존재를 왼쪽에 있는 존재와 같은 놈으로 만들어 준다. 파이썬에서도 양 변에 있는 두 존재가 같은지 비교하는 연산자는 ==이다.
예를들어
a = 1
b = a
a = 11
print(a)
print(b)
b = a
a = 11
print(a)
print(b)
이런 프로그램을 실행시키면 파이썬의 출력은
11
1
이 된다. 즉, 이 경우에는 변수 a의 값이 변수 b로 복사되고, a와 b는 아무 관련 없는 모르는 사이가 되었다. a를 바꾸더라도 b는 변하지 않는다.1
그런데
a = [10,20]
b = a
a[1]=11
print(a)
print(b)
위와 같은 프로그램을 실행시키면 출력은b = a
a[1]=11
print(a)
print(b)
[10, 11]
[10, 11]
이 된다. 이 경우에는, a와 b가 완전히 같은 존재가 되어 a를 바꾸면 b도 바뀌게 된다. 만약 a를 b로 복사해서 넣고 싶다면 copy 모듈을 불러와야 한다.[10, 11]
import copy
a = [10,20]
b = copy.copy(a)
a[1]=11
print(a)
print(b)
이렇게 하면 b는 a의 내용을 복사해서 받은 존재가 되어 a가 변해도 b는 변하지 않는다. (반대도 마찬가지) 따라서 이 프로그램의 출력은 다음과 같다.a = [10,20]
b = copy.copy(a)
a[1]=11
print(a)
print(b)
[10, 11]
[10, 20]
[10, 20]
아무튼. 직관적인 내용이므로 알면 편한데 문서 대충 읽고 개발하는 내게는 충격적이었다. 이게 왜 바뀌지? 싶은거...
물론 이런식으로 존재 자체에 대한 =연산자는 VB나 C/C++에는 없다. 별다른 생각 없이 직관적으로 =연산자를 사용해서 존재에 존재를 연관시키는 것이 장점이긴 한데, 존재의 종류에 따라 작동이 달라지는 것은 일관적이지는 않은 행동인것 같다. (물론, +연산자도 문자열 변수와 수치형 변수에 대해 다르게 작동하며 이것도 일관적인 행동은 아니다. 다만 직관적인 행동이다.)
댓글
우와~ 스럽네요.. -_-
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은 모든 것이 객체 이기 때문에, 모든 연산이 저렇게 구현되어 있고, 단하나의 예외도 없습니다.
1. 제가 만든 단어예요
2. 네...
3. 그렇군요...
4. 물론 그렇죠.
5. 파이썬을 어떻게 구현했는가는 제 관심 대상이 아닙니다.
음... 그냥 대충 배워서 대충 쓰고 싶은데 그렇게 깊이있게 알아야 하나요?
php 같은 경우는 = 사용시에 array 도 복사되기 때문에 snowall 님 의도대로 동작합니다.
얕은 복사가 당연한 것은 아닙니다. 단지 효율성이나 구현등의 문제겠죠.
PHP는 또 다른 구현을 갖고 있군요
네트의 세계는 역시 광대하네요 -_-
존재라는 표현 맘에 드는데요 전?
의미를 이해하는 게 중요한거 아닌가요?
자신의 지식을 뽐내고 싶어서 트집잡는 거 같네요
감사합니다 ㅎㅎ
포인터개념이 기본으로 밖혀 있군요.
C를 사용하는 저로서는 파격적이네요. ^^;;
그리고, 위의 기자분 전화번호를 남발하셔도 되는지... 심히 걱정되네요. ^^;;;;
그래서 연락드리고 지웠습니다.
VB를 쓰던 저로서도 파격적이긴 해요. VB에는... 한숨만 나오는 언어죠.
그러게요.. 기자분...좀 위험해 보이네요. ^^;