요즘 회사에서 파이썬을 사용한다.
얼마 전 사수분이 내게 이 말을 하셨다.
🧑💻 : 파이썬은
Call by Value & Reference
가 아니라 독자적인 호출 사용하는 거 아세여?
🐤 : . . . ? ? ?
안 그래도 요즘 파이썬 때문에 스트레스인데, 공부할 게 더 늘어난 것이다.
왜 혼자 다른 방식을 추구하는가..? 기분 나쁘게 내 마음을 자꾸 흔든다.
이왕 이렇게 된 거 이론 복습할 겸, 파이썬은 어떠한 방식으로 인자를 참조하는지 알아보자.
대부분의 프로그래밍 언어에서는 함수(또는 메소드)를 사용한다.
이 때 함수의 매개변수(argument)를 다루는 방법이 다르다.
통상적으로 두 가지의 방법이 존재한다.
Call By Value
: 값에 의한 호출Call By Reference
: 참조에 의한 호출Call By Value
함수가 값을 전달받을 때 변수에 담긴 값을 복사하여 전달받는다.
무슨 뜻이냐면 변수를 함수에 전달하여 내부에서 값을 변경하여도
복사된 값을 사용하기 때문에, 원본 값은 바뀌지 않는다는 것이다.
아래의 예시를 보자.
myName = "Lee Jae Chan"
print(f"내 이름은 {myName}.")
def changeName(name):
name = "이재찬"
return name
print(f"내 이름은 {changeName(myName)}")
print(f"그렇다면 과연 현재 이름은 ? : {myName}")
결과
===
내 이름은 Lee Jae Chan.
내 이름은 이재찬
그렇다면 과연 현재 이름은 ? : Lee Jae Chan
현재 changeName
함수에서 myName
이라는 인자를 넘겨 값을 변경하였다.
하지만 myName
의 값은 그대로인 것을 확인할 수 있다.
함수에 사용된 값은 결국 메소드 내에 복사된 값을 사용한 것이다.
함수가 값을 전달 받을 때, 원본 변수를 직접 수정할 수 있다.
위에서 설명한 call by value
와 달리, 변수를 함수 인자로 넘길 경우 해당 변수도 영향을 받는 것이다.
아래 예시를 보자.
my_info = ["Jae Chan", "Male", "2000.07.31"]
print(f"현재 원본 리스트: {my_info}")
def modifyList(list):
list.append(4)
list.append(5)
return list
print("변경된 리스트:", modifyList(my_info))
print("함수 호출 후 원본 리스트:", my_info)
결과
===
현재 원본 리스트: ['Jae Chan', 'Male', '2000.07.31']
변경된 리스트: ['Jae Chan', 'Male', '2000.07.31', 4, 5]
함수 호출 후 원본 리스트: ['Jae Chan', 'Male', '2000.07.31', 4, 5]
결과에서 볼 수 있듯이 현재 변수 값이 변경된 것을 확인할 수 있다.
이는 함수가 변수의 메모리 주소값을 바라보고 있기 때문이다.
장점 : 메모리 사용량이 줄어든다. 함수에 복사된 객체가 아니라 참조만 전달되기 때문에.
단점 : 원본 객체가 변경될 수 있어서 부작용이 발생할 수 있다.
근데 파이썬은 둘 다 사용을 안한다. 기존 지식에 혼동이 생긴 것이다.
그럼 파이썬은 무엇을 사용하는가?
공식문서에 의하면 다음과 같이 칭한다.
제목에서 알 수 있듯 어떠한 객체를 전달하냐에 따라 달라진다.
여기서 다른 프로그래밍 언어와 다른 점은 파이썬의 모든 변수는 객체이다.
파이썬에는 두 가지의 자료형이 존재한다.
int
, float
, string
등 List
, Dictionary
, Tuple
등 . . . 불변형의 경우, call by value
를 사용하고
가변형의 경우, call by reference
방식을 사용한다고 한다.
이유는 간단하다.
불변형 자료형 객체는 불변형이라 함수 내부에서는 기존 값이 아닌 복사된 값을 사용하여 새로운 값을 만든다.
가변형 자료형 객체의 경우는 새로운 값을 만드는 게 아닌, 기존 값에 다른 값이 추가되기 때문이다.
더 깊게 정리하고 넘어가고 싶은데 나중에 시간이 되면 더 다루겠다.
파이썬은 다른 애들 쓰는 방식 안 쓰고 눈치 없이 자기 멋대로 쓰고 싶은 거 쓴다.
🪨 Immutable 객체 : Call by value
형식을 채택
⭐ Mutable 객체 : Call by reference
형식을 채택
참고
Python 공식 문서