programing

파이썬 문자열은 불변 아닌가요?그렇다면 왜 a + " " + b가 작동합니까?

bestprogram 2023. 7. 21. 21:47

파이썬 문자열은 불변 아닌가요?그렇다면 왜 a + " " + b가 작동합니까?

제가 알기로는 파이썬 문자열은 불변입니다.

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

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
# !!!

파이썬이 과제를 막았어야 하지 않았나요?저는 아마 무언가를 놓치고 있을 것입니다.

감 잡히는 게 없어요?

첫째번▁firsta"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가 객체 "Dog"를 가리키고 있습니다.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'
----------------------------------------------------------------------

우리는.

유형 오류: '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"

+ " " + csays add" "현재 세트까지그럼 뭘 줘요?c변경할 수 없는 항목을 가리키고 현재 작업 세트에 추가합니다. 메모리:

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

마내침.a =says는 결과 집합을 가리키도록 내 포인터를 설정합니다.

메모리:

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

"Dog"더 이상 포인터가 메모리 청크에 연결되지 않으므로 회수됩니다.우리는 메모리 섹션을 수정한 적이 없습니다."Dog"불변의 의미인 상주했습니다.그러나 메모리의 해당 섹션을 가리키는 레이블을 변경할 수 있습니다.

데이터와 연관된 레이블 사이에는 차이가 있습니다.예를 들어 당신이 할 때.

a = "dog"

료자"dog"생성되어 레이블 아래에 배치됩니다.a레이블은 변경될 수 있지만 메모리에 있는 내용은 변경되지 않습니다. 데터"dog"를 실행한 까지) 합니다.

a = "cat"

의 에서.a이제 ^는 ^을 가리킵니다."cat" 러그나라는 문자열은"dog"변하지 않았습니다.

l = [1,2,3]
print id(l)
l.append(4)
print id(l) #object l is the same

a = "dog"
print id(a)
a = "cat"
print id(a) #object a is a new object, previous one is deleted

Python 문자열은 변경할 수 없습니다. 하만지,a문자열이 아닙니다. 문자열 값을 가진 변수입니다.문자열을 변환할 수는 없지만 변수의 값을 새 문자열로 변경할 수는 있습니다.

Python 문자열 개체는 변경할 수 없습니다.예:

>>> a = 'tanim'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281536'
>>> a = 'ahmed'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281600'

이 예에서는 에서 다른 값을 할당해도 수정되지 않음을 알 수 있습니다.새 개체가 생성됩니다.
그리고 그것은 수정될 수 없습니다.예:

  >>> a[0] = 'c'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    **TypeError**: 'str' object does not support item assignment

오류가 발생합니다.

변수는 원하는 곳을 가리킬 수 있습니다.다음 작업을 수행하면 오류가 발생합니다.

a = "dog"
print a                   #dog
a[1] = "g"                #ERROR!!!!!! STRINGS ARE IMMUTABLE

'mutable'은 문자열의 내용을 바꿀 수 있다는 뜻이고, 'mutable'은 문자열을 추가할 수 없다는 뜻입니다.

click for photo proof

a = 'dog'
address = id(a)
print(id(a))

a = a + 'cat'
print(id(a))      #Address changes

import ctypes
ctypes.cast(address, ctypes.py_object).value    #value at old address is intact

>>> a = 'dogs'

>>> a.replace('dogs', 'dogs eat treats')

'dogs eat treats'

>>> print a

'dogs'

불변이죠, 그렇죠?

변수 변경 부분은 이미 논의되었습니다.

예제에 이 추가 사항을 고려합니다.

 a = "Dog"
 b = "eats"
 c = "treats"
 print (a,b,c)
 #Dog eats treats
 d = a + " " + b + " " + c
 print (a)
 #Dog
 print (d)
 #Dog eats treats

블로그에서 찾은 가장 정확한 설명 중 하나는 다음과 같습니다.

파이썬에서 (거의) 모든 것은 객체입니다.Python에서 일반적으로 "변수"라고 부르는 것을 더 적절하게 이름이라고 합니다.마찬가지로, "할당"은 실제로 객체에 대한 이름의 바인딩입니다.각 바인딩에는 가시성을 정의하는 범위(일반적으로 이름이 시작되는 블록)가 있습니다.

예:

some_guy = 'Fred'
# ...
some_guy = 'George'

우리가 나중에 some_bullet = 'George'라고 말할 때, 'Fred'를 포함하는 문자열 객체는 영향을 받지 않습니다.방금 some_guy라는 이름의 바인딩을 변경했습니다.그러나 'Fred' 또는 'George' 문자열 개체는 변경하지 않았습니다.우리가 아는 한, 그들은 무기한으로 살 수 있습니다.

블로그 링크: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

위에서 언급한 답변에 조금 더 추가합니다.

id재할당 시 변수가 변경되는 경우.

>>> a = 'initial_string'
>>> id(a)
139982120425648
>>> a = 'new_string'
>>> id(a)
139982120425776

그 말은 우리가 변수를 변형시켰다는 것을 의미합니다.a새 문자열을 가리킵니다.이제 두 가지가 존재합니다. stringstr) 객체:

'initial_string'와 함께id= 139982120425648

그리고.

'new_string'와 함께id= 139982120425776

다음 코드를 고려합니다.

>>> b = 'intitial_string'
>>> id(b)
139982120425648

지금이다,b는 가는말키리을을 .'initial_string'그리고 같은 것을 가지고 있습니다.id~하듯이a재할당 전에 가지고 있었습니다.

그므로러는,'intial_string'변형되지 않았습니다.

기능 내장기입니다.id()개체의 ID를 정수로 반환합니다.이 정수는 일반적으로 메모리에서 개체의 위치에 해당합니다.

\>>a='dog'
\>>print(id(a))

139831803293008

\>>a=a+'cat'
\>>print(id(a))

139831803293120

처음에 'a'는 139831803293008 메모리 위치에 저장되는데, 이는 python에서 문자열 개체가 불변하기 때문입니다. 만약 당신이 참조를 수정하고 재할당하려고 한다면, 제거될 것이고 새로운 메모리 위치(139831803293120)에 대한 포인터가 될 것입니다.

요약:

a = 3
b = a
a = 3+2
print b
# 5

불변이 아님:

a = 'OOP'
b = a
a = 'p'+a
print b
# OOP

불변:

a = [1,2,3]
b = range(len(a))
for i in range(len(a)):
    b[i] = a[i]+1

이것은 Python 3의 오류입니다. 왜냐하면 이것은 불변이기 때문입니다.그리고 파이썬 2의 오류는 아닙니다. 왜냐하면 분명히 그것은 불변하지 않기 때문입니다.

두 문자열 값을 연결합니다.(a)의 값은 절대 변경하지 않습니다.방금 (a)는 "dog dog" 값을 가진 다른 메모리 블록을 나타냅니다.백엔드에서는 한 변수가 두 개의 메모리 블록을 동시에 나타내지 않기 때문입니다.연결 전 (a)의 값은 "dog"였습니다.하지만 그 이후에는 (a) "개"를 나타냅니다. 왜냐하면 이제 (a) 백엔드 담당자이기 때문입니다."dog dog" 값이 있는 블록.그리고 "dog"는 (b)에 의해 대표되며 "dog"는 (b)가 "dog"를 나타낼 때까지 쓰레기 값으로 계산되지 않습니다.

여기서 혼동되는 것은 백엔드에 동일한 변수 이름을 가진 메모리 블록(데이터 또는 정보 포함)을 표시한다는 것입니다.

Numpy 배열을 불변으로 만들고 첫 번째 요소를 사용할 수 있습니다.

numpyarrayname[0] = "write once"

그러면:

numpyarrayname.setflags(write=False)

또는

numpyarrayname.flags.writeable = False

이 이미지는 답을 제공합니다.제발 읽어.

enter image description here

언급URL : https://stackoverflow.com/questions/9097994/arent-python-strings-immutable-then-why-does-a-b-work