[python] 파이썬 문자열은 불변하지 않습니까? 그렇다면 a +“”+ b가 작동하는 이유는 무엇입니까?

내 이해는 Python 문자열은 변경할 수 없다는 것입니다.

다음 코드를 시도했습니다.

a = "Dog"
b = "eats"
c = "treats"

print a, b, c
# Dog eats treats

print a + " " + b + " " + c
# Dog eats treats

print a
# Dog

a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!

파이썬이 할당을 막아야하지 않았습니까? 나는 아마도 뭔가를 놓치고있을 것이다.

어떤 생각?



답변

먼저 a문자열 “Dog”를 가리 켰습니다. 그런 다음 a새 문자열 “Dog eats treats”를 가리 키 도록 변수 를 변경했습니다 . 실제로 “Dog”문자열을 변경하지 않았습니다. 문자열은 변경할 수 없으며 변수는 원하는 것을 가리킬 수 있습니다.


답변

문자열 객체 자체는 변경할 수 없습니다.

a문자열을 가리키는 변수 는 변경 가능합니다.

치다:

a = "Foo"
# a now points to "Foo"
b = a
# b points to the same "Foo" that a points to
a = a + a
# a points to the new string "FooFoo", but b still points to the old "Foo"

print a
print b
# Outputs:

# FooFoo
# Foo

# Observe that b hasn't changed, even though a has.


답변

변수 a는 개체 “개”를 가리 킵니다. Python의 변수를 태그로 생각하는 것이 가장 좋습니다. 당신은 당신이 변화 할 때 당신이 무슨 짓을하는 다른 개체에 태그를 이동할 수 있습니다 a = "dog"a = "dog eats treats".

그러나 불변성은 태그가 아니라 객체를 의미합니다.


당신이 노력하면 a[1] = 'z'"dog""dzg", 당신은 오류를 얻을 것이다 :

TypeError: 'str' object does not support item assignment" 

문자열은 항목 할당을 지원하지 않기 때문에 변경할 수 없습니다.


답변

메모리 위치 자체를 변경하지 않고 메모리 위치에있는 값을 변경할 수있는 경우에만 무언가 변경 가능합니다.

트릭은 다음과 같습니다. 변경 전후의 메모리 위치가 동일하면 변경 가능합니다.

예를 들어 목록은 변경 가능합니다. 어떻게?

>> a = ['hello']
>> id(a)
139767295067632

# Now let's modify
#1
>> a[0] = "hello new"
>> a
['hello new']
Now that we have changed "a", let's see the location of a
>> id(a)
139767295067632
so it is the same as before. So we mutated a. So list is mutable.

문자열은 변경할 수 없습니다. 어떻게 증명합니까?

> a = "hello"
> a[0]
'h'
# Now let's modify it
> a[0] = 'n'
----------------------------------------------------------------------

우리는 얻는다

TypeError : ‘str’개체는 항목 할당을 지원하지 않습니다.

그래서 우리는 문자열 변형에 실패했습니다. 그것은 문자열이 불변임을 의미합니다.

재 할당 할 때 새 위치 자체를 가리 키도록 변수를 변경합니다. 여기에서는 문자열을 변경하지 않고 변수 자체를 변경했습니다. 다음은 당신이하는 일입니다.

>> a = "hello"
>> id(a)
139767308749440
>> a ="world"
>> id(a)
139767293625808

id재 할당 전후가 다르기 때문에 실제로 변이가 아니라 변수를 새 위치로 가리키고 있음을 증명합니다. 그 문자열을 변경하는 것이 아니라 해당 변수를 변경하는 것입니다.


답변

변수는 객체를 가리키는 레이블 일뿐입니다. 개체는 변경할 수 없지만 원하는 경우 레이블이 완전히 다른 개체를 가리 키도록 만들 수 있습니다.


답변

치다:

>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='qwer'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x109198490>

같은 값을 변수에 두 번 저장했을 때 16 진수 메모리 위치는 변경되지 않았습니다. 다른 값을 저장하면 변경되었습니다. 문자열은 변경할 수 없습니다. 열광 때문이 아니라 메모리에 새 개체를 만드는 성능 저하를 지불하기 때문입니다. 변수 a는 해당 메모리 주소를 가리키는 레이블입니다. 무엇이든 가리 키도록 변경할 수 있습니다.


답변

명령문 a = a + " " + b + " " + c은 포인터를 기반으로 세분화 할 수 있습니다.

a + " "걸 줄 말한다 a변경할 수 없습니다 수있는 가리키는 및 추가 " "내 현재 작업 세트에.

기억:

working_set = "Dog "
a = "Dog"
b = "eats"
c = "treats"

+ b걸 줄 말한다 b변경할 수 없습니다 수있는 가리키는 및 현재 작업 세트에 추가합니다.

기억:

working_set = "Dog eats"
a = "Dog"
b = "eats"
c = "treats"

+ " " + c" "현재 세트에 추가 를 말합니다 . 그런 다음 c변경할 수없는 점을 알려주고 현재 작업 세트에 추가하십시오. 기억:

working_set = "Dog eats treats"
a = "Dog"
b = "eats"
c = "treats"

마지막으로 a =결과 집합을 가리 키도록 포인터를 설정합니다.

기억:

a = "Dog eats treats"
b = "eats"
c = "treats"

"Dog"더 이상 포인터가 메모리 덩어리에 연결되지 않기 때문에 회수됩니다. 우리는 상주하는 메모리 섹션을 수정하지 않았습니다 "Dog". 그러나 메모리의 해당 섹션을 가리키는 레이블 (있는 경우)을 변경할 수 있습니다.