class ABC:
def __init__(self, a: int, b: int):
self.a = a
self.b = b
def change_value(abc: ABC):
abc.a = 10
abc.b = 20
def change_value2(a: int, b: int):
a = 10
b = 20
abc = ABC(1, 2)
change_value2(abc.a, abc.b)
print(abc.a, abc.b) # 1 2
change_value(abc)
print(abc.a, abc.b) # 10 20
"값에 의한 전달"(pass by value)과 "참조에 의한 전달"(pass by reference)은 함수에 인자를 넘기는 방식을 설명할 때 사용되는 용어입니다. 이 두 방식은 함수가 인자의 데이터를 어떻게 처리하는지에 대한 핵심적인 차이점을 나타냅니다.
실제 값(value)의 복사본이 생성되어 함수에 전달됩니다.인자의 메모리 주소(reference)가 함수에 전달됩니다.Python은 좀 더 세밀한 차이를 가지고 있는데, "객체 참조에 의한 전달"(pass by object reference) 방식을 사용합니다. 이는 함수에 인자를 전달할 때, 객체의 참조(메모리 주소)가 전달되지만, 객체 자체가 아니라 객체의 참조(메모리 주소)가 복사되어 전달된다는 점에서 참조에 의한 전달과 다릅니다. 따라서,
def add_item(list_example):
list_example.append(4) # 기존 객체를 변경
def change_reference(list_example):
list_example = [4, 5, 6] # 새로운 객체로 참조를 변경
my_list = [1, 2, 3]
add_item(my_list)
print(my_list) # 출력: [1, 2, 3, 4], 기존 객체가 변경됨
change_reference(my_list)
print(my_list) # 출력: [1, 2, 3, 4], 외부의 my_list는 변경되지 않음
change_value2 함수를 호출했을 때 abc.a와 abc.b가 바뀌지 않는 이유는 Python에서 함수에 인자를 전달할 때 "값에 의한 전달"(pass by value) 방식이 아니라 "참조에 의한 전달"(pass by reference) 방식을 사용하지만, 이는 기본 타입(예: 정수, 실수, 문자열 등)에 대해서는 실질적으로 "값에 의한 호출"처럼 동작하기 때문입니다. 즉, change_value2 함수에 abc.a와 abc.b를 인자로 전달하면, 이들의 값이 복사되어 전달되며, 함수 내에서 a와 b 변수의 값을 변경해도 원본 abc.a와 abc.b에는 영향을 주지 않습니다.
abc.a와 abc.b를 변경하고 싶다면, 몇 가지 해결 방안이 있습니다:
객체를 직접 전달하기: change_value 함수처럼 객체 자체를 전달하고, 함수 내에서 객체의 속성을 변경합니다. 이 방법은 이미 코드에서 구현되어 있으며, 객체의 속성을 직접 변경하여 원하는 결과를 얻습니다.
값을 반환하여 업데이트하기: change_value2 함수를 수정하여 a와 b의 새로운 값을 반환하고, 이를 사용하여 abc.a와 abc.b를 업데이트할 수 있습니다. 예를 들어:
class ABC:
def __init__(self, a: int, b: int):
self.a = a
self.b = b
def change_value(abc: ABC):
abc.a = 10
abc.b = 20
def change_value2(a: int, b: int) -> (int, int):
a = 10
b = 20
return a, b
abc = ABC(1, 2)
abc.a, abc.b = change_value2(abc.a, abc.b)
print(abc.a, abc.b) # 출력: 10 20
change_value(abc)
print(abc.a, abc.b) # 출력: 10 20
이 방식에서 change_value2 함수는 새로운 a, b 값을 반환하고, 이를 통해 abc.a, abc.b를 업데이트합니다. 이 방법은 함수가 값을 변경하고 그 결과를 호출자에게 명시적으로 반환할 때 유용합니다.
Python에서 기본 타입의 값은 함수에 인자로 전달될 때 값이 복사되어 전달되기 때문에, 함수 내부에서 이 값을 변경해도 원본에 영향을 주지 않습니다. 객체의 속성을 변경하고자 할 때는 객체를 직접 전달하거나, 변경된 값을 반환하고 호출자가 이를 사용하여 객체를 업데이트하는 방법을 사용해야 합니다.