2.책에 p44에 보면 함수에서 매개 변수가 call-by-reference 형태로 들어가는데 매개변수가 변경 불가능한 변수일
때는 행동을 달리한다고 했는데, 즉 매개변수가 int 형 일때는 call-by-value처럼 행동하는거 같은데 모든 함수가
call-by-reference 인데 행동을 call-by-value처럼 하는 것인지 아니면 int형을 매개로 받는 것은
call-by-value로 만든것인지 명확하지 않습니다.
3. 그리고 어떤 자료형이 변경 불가능한 변수인지 어떤 자료형이 변경 가능한 자료인지 정확하게 알려주셨으면 합니다.
4. 다음과 같은 코드가 있을때
def changeList(a):
a = [2,3]
a = [1]
changeList(a)
변수가 a 가 왜 변하지 않는걸까요? 예제에서 list를 구성하는 하나의 값을 변경했을때는 변경된 값이 리스트 변수에 반영되는
데 위는 왜 그렇지 않을까요?
여러가지 혼란 스러운 점을 있습니다. 꼭 알려주시기 바랍니다.
아래는 질문에 대한 답입니다.
1. 네 맞습니다.
2. 함수의 인수는 모두 레퍼런스를 이용해 주고 받습니다. int도 레퍼런스로 입력을 주고 받습니다.
44페이지의 함수가 call-by-value로 동작하는 것 처럼 보이는 이유는 파이선이 C/C++의
call-by-reference와 다르기 때문입니다.
44페이지 중간의 예제를 가지고 설명 하자면, 입력 한 변수와 함수를 통과한 변수가 서로 같기 때문에 call-by-
value로 보이지만 사실 함수내에서 x
= 1은 입력 한 값을 변경 하는 것이 아니라 x라는 이름을 가진 새로운 객체를 생성하는 것입니다.
3. 일단 기본적으로 거의 대부분 immutable 이라고 보시면 됩니다. ( int, float, ...)
사전(Dictionary)은 mutable이고 리스트도 mutable입니다.
반면 튜플(Tuple)은 immutable 입니다.
이외의 객체들은 mutable, immutable인지 잘 살펴보고 코딩을 해야 합니다.
대부분의 경우 document에 mutable, immutable인지 표기 되어 있지만, (immutable인 경우는 안
적는 경우도 많습니다.)
아닌 경우도 있기 때문에 주의 해야 합니다.
4.
List는 변경 가능한 변수입니다. 그렇게 때문에 함수에서 값을 변경 할 수 있습니다. 하지만
def changeList(a):
a = [2,3]
a = [1]
changeList(a)
에서 changeList를 거친 함수를 보면 a가 변경되지 않은 이유는 리스트를 변경한게 아니라. 리스트의 레퍼런스 a를 변경
한 것이기 때문입니다.
def changeList(a):
a = [2,3] ===> 2와 3을 가진 리스트를 생성하고 이 리스트의 레퍼런스를 a라고 지정한다.
즉 changeList의 인수로 받은 a 레퍼런스와 a=[2,3] 이후의 레퍼런스는 달라 지게 됩니다 ( 책 45페이지 상단
의 그림과 같은 꼴이 됩니다.)
예제를 가지고 직접 확인해 보겠습니다. id() 함수는 각 객체의 id를 정수로 리턴해 줍니다.
>>> a = [1]
>>> id(a)
39380712
>>> def changeList(a):
print("defore:",id(a))
a = [2,3]
print("after:",id(a))
>>> changeList(a)
defore: 39380712
after: 39380672
a = [2,3] 이후로 객체의 id가 바뀌는 걸 볼 수 있습니다. ( 2번도 id를 사용해서 객체가 생성하는 것을 확인 할
수 있습니다.)
원래 사용자의 의도는 입력 받은 리스트를 변경하고 싶었지만 함수내에서 새로운 리스트를 만든 결과입니다.
함수내에서 입력 받은 리스트를 변경하고 싶다면 책 46페이지 상단의 내용을 참고해주세요.
감사합니다.