Python Call by value, Call by reference
def swap(a, b):
a, b = b, a
print(a, b)
n, m = 10, 20
swap(n, m)
print(n, m)
위 코드를 실행하면
20 10
10 20
위 결과가 나온다.
위 코드는 n, m의 값을 바꿀 목적으로 작성했지만
함수 실행 시에만 변경된 값이 출력되며 실제로 n, m의 값은 바뀌지 않는 모습이다.
파이썬의 변수는 수정이 가능한 형식과 수정이 불가능한 형식이 있다.
수정 불가능한 객체는 immutable 객체라고 부른다. 수정 가능한 객체는 mutable 객체라고 부른다.
immutable 객체는 tuple, str, int, bool, float 등이 있고
mutable 객체는 list, dict등이 있다.
여기서 immutable 객체는 함수의 인자로 넘어가게되면 수정이 불가능한 특징 때문에 변수가 그대로 넘어가는 것이 아닌,
변수가 갖고 있던 값을 복사하여 값을 넘겨주게 된다.
위 코드의 int형식의 n과 m는 immutable 객체이기 때문에 변수 자체가 함수에 전달되지 않고 값이 복사되어 a, b에 전달된다. 그렇게 때문에 첫번째 출력결과는 의도대로 값이 swap되어 20과 10이 출력되지만, 두번째 출력 결과로는 n, m에 변화가 없었기 때문에 10과 20이 출력된다.
def swap(a, b):
a, b = b, a
return a, b
n, m = 10, 20
n, m = swap(n, m)
print(n, m)
앞서 말한 특성 때문에 값을 변경하는 함수를 작성하고 싶다면 위의 코드처럼 값을 반환하는 반환형 함수를 작성해서
값을 반환받아야 된다. 위 코드는 실행시 의도와 같이 값이 변경되어 20과 10이 출력된다.
def modify(arr):
arr[0] = 10
numlist = [1, 2, 3, 4]
modify(numlist)
for num in numlist:
print(num, end=" ")
10 2 3 4
반대로 mutable 객체인 list는 위와 같이 코드 작성 시 함수의 인자로 넘어갈 때 변수 자체의 주소가 넘어가게 되기 때문에
함수 안에서의 해당 인자에게 일어나는 변화가 함수 호출시 넘긴 변수에 저장된다.
위처럼 변화하는것이 싫다면 modify(numlist) 코드를
modify(numlist[:])로 수정하여 새로운 리스트를 만들어 전달하면 된다.
python에서는 함수에 값을 넘길때 인자값이 immutable 객체인지 mutable 객체인지 고려해야 한다.