일반적으로 사용하는 함수인자 전달방식은 2가지:
- call by value : 값에 의한 호출
- call by reference : 참조(주소)에 의한 호출
1. Call by Value
- 값에 의한 호출
- 변수에 할당 된 값만을 복사해서 함수의 인자로 넘기기
deft a_print(value):
print(value)
a= 2
a_print(a)
2라는 값이 메모리 상에 복사되어 value에 할당
a의 2와 value의 2는 서로 다른 위치의 메모리에 저장되어 있음!
2. Call by Reference
- 함수의 인자로 넘어간 값이 함수 내부에서 변경되면서 실제로 값이 변경 됨
- 참조를 호출하는 방식
- call by reference로 인자를 넘기면 메모리 상에 저장된 실제 값에 변경을 줄 수 있기 때문에 함수 외부에서도 값이 변경되는 것을 볼 수 있음
주의! 파이썬은 오직 passed by Assignment!
- 주의! python은 일반적인 함수 인자 전달 방식(위의 2가지)와 조금 다른 형태를 취함!
- 파이썬에서는 명시적인 call by reference 불가! (=call by assignment)
- 넘겨지는 객체의 종류에 따라서 call by reference 또는 call by value가 결정됨
- immutable object
ex) int, float, string, tuple (단일 값이거나, static 속성)
함수 argument로 넘어갈 때 call by value로 넘어감(복사)
- mutable object
ex) list, dict, set
mutalbe한 오브젝트가 argument로 넘어가면 object reference가 넘어가서 담고 있는 값을 바꿀 수 있음
즉! call by reference를 하고 싶다면, mutable 형태의 객체로 넘기거나,
class의 멤버 변수로 관리하여 접근을 용이하게 하는 방법 등이 있을 듯 하다고 함
>>>
>>> def func1(data):
... data = data + 1
...
>>> def func2(data):
... data[0] = data[0] + 1
...
>>>
>>> def main():
... data1 = 1
... data2 = [1]
... # Call by Value
... func1(data1)
... print('data1', data1)
... # Call by Reference
... print('data2', data2)
...
>>> if __name__ == '__main__':
... main()
...
data1 1
data2 [1]
>>>
a = 2
파이썬 언어의 특성으로 인해
'a = 2'라고 변수를 할당하면 2라는 값이 a가 가르키는 메모리 공간에 할당되는 것이 아니라!
'2라는 인스턴스의 주소값'을 a가 가르키게 됨!
'a += 1'을 할 경우,
실제로 값이 변경되는 것이 아니라, 가르키는 값이 변경되는 것임!
- 파이썬 객체들의 reference count
: 파이선의 객체들은 자신을 가르키고 있는 변수의 숫자(reference count)를 저장하고 있음
변수는 메모리 공간에 값을 직접 지정하지 않으며,
해당 값의 인스턴스를 가르키고
해당 인스턴스의 reference count를 증가시킨다
연상 등을 통해 변수가 가지는 값이 변경되더라도
실제 메모리에 저장된 값이 변경된느 것이 아니라
가르키고 있는 인스턴스가 변경됨!
Reference
더 살펴보기