나는 이것을한다:
a = 'hello'
이제 저는 다음의 독립된 사본을 원합니다 a
.
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
출력 [3] :
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
왜 모두 같은 메모리 주소를 가지고 있고 어떻게 사본을 얻을 수 a
있습니까?
답변
Python 문자열을 복사 할 필요 가 없습니다 . 그것들은 불변이며, copy
모듈은 do str()
, 전체 문자열 슬라이스 및 빈 문자열로 연결하는 경우와 같은 경우 항상 원본을 반환 합니다.
또한, 귀하의 'hello'
문자열은 인턴됩니다 ( 특정 문자열은 ). 파이썬은 딕셔너리 조회 속도를 높이기 때문에 의도적으로 하나의 복사본 만 유지하려고합니다.
이 문제를 해결할 수있는 한 가지 방법은 실제로 새 문자열을 만든 다음 해당 문자열을 다시 원래 내용으로 분할하는 것입니다.
>>> a = 'hello'
>>> b = (a + '.')[:-1]
>>> id(a), id(b)
(4435312528, 4435312432)
하지만 지금하고있는 일은 기억을 낭비하는 것뿐입니다. 결국 이러한 문자열 객체를 어떤 식 으로든 변경할 수있는 것처럼 보이지는 않습니다.
알고 싶은 것이 파이썬 객체에 필요한 메모리 양뿐이라면 sys.getsizeof()
; 모든 Python 객체의 메모리 공간을 제공합니다.
용기의 경우 내용물 이 포함 되지 않습니다 . 총 메모리 크기를 계산하려면 각 컨테이너로 재귀해야합니다.
>>> import sys
>>> a = 'hello'
>>> sys.getsizeof(a)
42
>>> b = {'foo': 'bar'}
>>> sys.getsizeof(b)
280
>>> sys.getsizeof(b) + sum(sys.getsizeof(k) + sys.getsizeof(v) for k, v in b.items())
360
그런 다음 id()
추적을 사용하여 실제 메모리 공간을 사용하거나 객체가 캐시 및 재사용되지 않은 경우 최대 공간을 추정 하도록 선택할 수 있습니다 .
답변
문자열 형식을 통해 파이썬에서 문자열을 복사 할 수 있습니다.
>>> a = 'foo'
>>> b = '%s' % a
>>> id(a), id(b)
(140595444686784, 140595444726400)
답변
방금 문자열 조작을 시작 하고이 질문을 찾았습니다. 나는 아마도 OP, “보통 나”와 같은 것을하려고했을 것이다. 이전 답변은 내 혼란을 해결하지 못했지만 그것에 대해 조금 생각한 후에 마침내 “알았습니다”.
만큼 a
, b
, c
, d
,과 e
동일한 값을 갖고, 이들은 동일 위치에 참조. 메모리가 저장됩니다. 변수가 다른 값을 갖기 시작하자마자 다른 참조를 갖기 시작합니다. 내 학습 경험은 다음 코드에서 나왔습니다.
import copy
a = 'hello'
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
print map( id, [ a,b,c,d,e ] )
print a, b, c, d, e
e = a + 'something'
a = 'goodbye'
print map( id, [ a,b,c,d,e ] )
print a, b, c, d, e
인쇄 된 출력은 다음과 같습니다.
[4538504992, 4538504992, 4538504992, 4538504992, 4538504992]
hello hello hello hello hello
[6113502048, 4538504992, 4538504992, 4538504992, 5570935808]
goodbye hello hello hello hello something
답변
문자열 복사는 두 가지 방법으로 수행 할 수 있습니다. a = “a”b = a 위치를 복사하거나 a = ‘a’b = a [:]에 의해 수행되는 a가 변경 될 때 b가 영향을받지 않음을 의미하는 복제 할 수 있습니다.
답변
다르게 말하면 “id ()”는 당신이 신경 쓰는 것이 아닙니다. 소스 변수 이름을 손상시키지 않고 변수 이름을 수정할 수 있는지 알고 싶습니다.
>>> a = 'hello'
>>> b = a[:]
>>> c = a
>>> b += ' world'
>>> c += ', bye'
>>> a
'hello'
>>> b
'hello world'
>>> c
'hello, bye'
C에 익숙하다면 포인터 변수와 비슷하지만 가리키는 내용을 수정하기 위해 역 참조 할 수는 없지만 id ()는 현재 가리키는 위치를 알려줍니다.
파이썬 프로그래머의 문제는 목록이나 사전과 같은 더 깊은 구조를 고려할 때 발생합니다.
>>> o={'a': 10}
>>> x=o
>>> y=o.copy()
>>> x['a'] = 20
>>> y['a'] = 30
>>> o
{'a': 20}
>>> x
{'a': 20}
>>> y
{'a': 30}
여기서 o와 x는 동일한 dict o [ ‘a’]와 x [ ‘a’]를 나타내며 그 dict는 키 ‘a’의 값을 변경할 수 있다는 의미에서 “변경 가능”합니다. 그렇기 때문에 “y”는 사본이어야하고 y [ ‘a’]는 다른 것을 참조 할 수 있습니다.