class Number:
def __init__(self, number):
self.number = number
def my_function(self):
self.number[0] = 100
return self.number
numlist = [1, 2, 3]
num1 = Number(numlist).my_function()
print(num1)
# [100, 2, 3]
print(numlist)
# [100, 2, 3] # ???
예시 클래스 Number을 보자.
① 생성자 __init__() 메소드로 받은 인자를 인스턴스 변수로 만들어주고
② my_function() 메소드로 인덱스가 0인 자리를 100으로 바꾸어주는 클래스이다.
우리는 numlist를 만들고, 그 numlist를 인자로 넣은 클래스 객체 num1을 만들었다.
numlist를 클래스 내의 메소드를 통해 조작한 결과가 num1이니까,
num1의 인덱스 0이 100으로 바뀔 것이고, 여기까지는 원하는 대로 되었지만..
문제는 원본 객체 numlist의 인덱스 0도 100으로 바뀐 것을 확인할 수 있다.
이유는 id() 함수를 통해 알아낼 수 있다.
>>> print(id(numlist))
# 18761208
>>> print(id(num1))
# 18761208
id()는 두 객체의 메모리 주소 (memory address)를 확인하는 함수이다.
이 두 객체는 같은 메모리 주소를 가리키고 있다.
__init__() 메소드에서 self.numlist = numlist라는 코드는 numlist의 복사본이 numlist와 같은 객체임을 말한다.
따라서 이런 문제를 해결하기 위해서는 단순히 a = b로 복사하는 것이 아니라,
class Number:
def __init__(self, number):
self.number = number[:]
def my_function(self):
self.number[0] = 100
return self.number
numlist = [1, 2, 3]
num1 = Number(numlist).my_function()
print(num1)
# [100, 2, 3]
print(numlist)
# [1, 2, 3]
print(id(numlist))
# 55199224
print(id(num1))
# 55200384
이렇게 [:]를 이용해서 복사하면 된다. [:]는 리스트 슬라이싱을 할 때 쓰는데, 자를 부분을 인자로 넣지 않았기 때문에
전체 리스트를 리턴하게 된다.
이제 id() 함수로 메모리 주소를 확인하면, 두 객체는 다른 메모리 주소를 가리키고 있음을 알 수 있다.
'Computer Science > [20-3,4] Python Basic' 카테고리의 다른 글
[Python] csv 파일에서 특정 단어를 가진 열 찾아보기 (0) | 2020.04.22 |
---|---|
[Python] Operator Overloading (3) 클래스 객체 간의 연산과 역순 연산자 (0) | 2020.04.02 |
[Python] Operator Overloading (2) iterator 구현해보기 (0) | 2020.04.02 |
[Python] Operator Overloading (1) == 연산자 재정의하기 (0) | 2020.04.01 |
[Python] Optional Parameter에 None 주의해서 쓰기 (0) | 2020.04.01 |
댓글