불변 유형이 무엇인지 혼란 스럽습니다. 필자의 float
책에서 이러한 유형의 예제를 사용 하면 객체가 변경 불가능한 것으로 간주됩니다.
class RoundFloat(float):
def __new__(cls, val):
return float.__new__(cls, round(val, 2))
이것은 클래스 구조 / 계층 때문에 불변으로 간주됩니까?, 의미 float
는 클래스의 최상위에 있으며 자체 메서드 호출입니다. 이 유형의 예제와 비슷합니다 (내 책 dict
이 변경 가능 하다고 말하더라도 ).
class SortedKeyDict(dict):
def __new__(cls, val):
return dict.__new__(cls, val.clear())
변경 가능한 것은 클래스 내부에 메소드가 있지만이 유형의 예제는 다음과 같습니다.
class SortedKeyDict_a(dict):
def example(self):
return self.keys()
또한 마지막 class(SortedKeyDict_a)
유형에 대해이 유형의 세트를 전달하면 :
d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))
example
메소드 를 호출하지 않고 사전을 리턴합니다. SortedKeyDict
와 __new__
오류로 플래그를. RoundFloat
클래스에 정수를 전달하려고 시도했지만 __new__
오류가 표시되지 않았습니다.
답변
뭐? 플로트는 불변입니까? 하지만 난 못해
x = 5.0
x += 7.0
print x # 12.0
“mut”x 아닌가?
글쎄, 문자열이 변경 불가능하다는 데 동의합니까? 그러나 같은 일을 할 수 있습니다.
s = 'foo'
s += 'bar'
print s # foobar
변수의 값은 변하지 만 변수가 참조하는 것을 변경하면 변합니다. 변경 가능한 유형은 이러한 방식으로 변경 될 수 있으며 “제자리에서”변경 될 수도 있습니다.
차이점이 있습니다.
x = something # immutable type
print x
func(x)
print x # prints the same thing
x = something # mutable type
print x
func(x)
print x # might print something different
x = something # immutable type
y = x
print x
# some statement that operates on y
print x # prints the same thing
x = something # mutable type
y = x
print x
# some statement that operates on y
print x # might print something different
구체적인 예
x = 'foo'
y = x
print x # foo
y += 'bar'
print x # foo
x = [1, 2, 3]
y = x
print x # [1, 2, 3]
y += [3, 2, 1]
print x # [1, 2, 3, 3, 2, 1]
def func(val):
val += 'bar'
x = 'foo'
print x # foo
func(x)
print x # foo
def func(val):
val += [3, 2, 1]
x = [1, 2, 3]
print x # [1, 2, 3]
func(x)
print x # [1, 2, 3, 3, 2, 1]
답변
파이썬은 모든 데이터를 객체로 나타냅니다. 목록 및 사전과 같은 일부 개체는 변경 가능하므로 ID를 변경하지 않고 내용을 변경할 수 있습니다. 정수, 부동 수, 문자열 및 튜플과 같은 다른 객체는 변경할 수없는 객체입니다. 이해하기 쉬운 방법은 객체 ID를 살펴 보는 것입니다.
아래에는 불변의 문자열이 있습니다. 내용을 변경할 수 없습니다. 그것은을 올릴 것이다 TypeError
당신이 그것을 변경하려고합니다. 또한 새 컨텐츠를 할당하면 컨텐츠를 수정하는 대신 새 오브젝트가 작성됩니다.
>>> s = "abc"
>>>id(s)
4702124
>>> s[0]
'a'
>>> s[0] = "o"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> s = "xyz"
>>>id(s)
4800100
>>> s += "uvw"
>>>id(s)
4800500
목록으로 그렇게 할 수 있으며 객체의 정체성을 바꾸지 않습니다.
>>> i = [1,2,3]
>>>id(i)
2146718700
>>> i[0]
1
>>> i[0] = 7
>>> id(i)
2146718700
Python의 데이터 모델에 대한 자세한 내용을 보려면 Python 언어 참조를 살펴보십시오.
답변
일반적인 불변 유형 :
- 번호 :
int()
,float()
,complex()
- 불변 서열 :
str()
,tuple()
,frozenset()
,bytes()
일반적인 가변 유형 (거의 모든 것) :
- 가변 시퀀스 :
list()
,bytearray()
- 세트 유형 :
set()
- 매핑 유형 :
dict()
- 클래스, 클래스 인스턴스
- 기타
유형이 변경 가능한지 여부를 신속하게 테스트하는 한 가지 방법은 id()
내장 기능 하는 것입니다.
정수를 사용하는 예,
>>> i = 1
>>> id(i)
***704
>>> i += 1
>>> i
2
>>> id(i)
***736 (different from ***704)
목록을 사용하여
>>> a = [1]
>>> id(a)
***416
>>> a.append(2)
>>> a
[1, 2]
>>> id(a)
***416 (same with the above id)
답변
우선, 클래스에 메소드가 있는지 또는 클래스 구조가 변경되는지 여부는 변경 가능성과 관련이 없습니다.
int
s 및 float
s는 변경할 수 없습니다 . 만약 내가한다면
a = 1
a += 5
이름 a
이1
첫 번째 행의 메모리 어딘가에 . 두 번째 줄에, 그를 조회 1
, 추가 5
취득, 6
다음 점을 a
그에서 6
메모리에 – 그것은하지 않았다 변경1
A와를 6
어떤 식 으로든. 다른 변경 불가능한 유형을 사용하여 다음 예제에 동일한 논리가 적용됩니다 .
b = 'some string'
b += 'some other string'
c = ('some', 'tuple')
c += ('some', 'other', 'tuple')
내용은 변경 가능한 유형, 나는 actallly 일 할 수있는 이 메모리에 저장된 값을 변경을 . 와:
d = [1, 2, 3]
나는의 위치 목록을 만들었습니다 1
, 2
그리고 3
메모리를. 내가한다면
e = d
난 그냥 포인트 e
받는 동일한list
d
에서 포인트. 그런 다음 할 수 있습니다 :
e += [4, 5]
그리고 지점 e
과 d
지점이 업데이트되어 목록이 4
및5
메모리를.
불변 유형 으로 돌아가서 tuple
다음 과 같이하면 :
f = (1, 2, 3)
g = f
g += (4, 5)
그때 f
여전히 원본tuple
만 가리 킵니다 g
. 완전히 새로운 것을 가리 켰 습니다.tuple
. .
이제, 당신의 예를 들어
class SortedKeyDict(dict):
def __new__(cls, val):
return dict.__new__(cls, val.clear())
당신이 통과하는 곳
d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))
(A 인 tuple
의 tuples
등) val
때문에, 오류를 받고있어 tuple
의가없는 .clear()
방법을 – 당신이 통과해야 할 것 dict(d)
같은 val
일에 대한 당신이 빈 얻을 것이다 경우에, SortedKeyDict
결과를.
답변
다른 언어 (루비와 같이 파이썬과 비슷한 언어는 제외)에서 파이썬으로오고 다른 언어로 이해하려고하면 사람들이 혼란스러워하는 부분은 다음과 같습니다.
>>> a = 1
>>> a = 2 # I thought int was immutable, but I just changed it?!
파이썬에서 할당은 파이썬에서 돌연변이가 아닙니다.
C ++ 에서을 쓰면을 a = 2
호출 a.operator=(2)
하여에 저장된 객체를 변경합니다 a
. (그리고 저장된 물건 이 없다면a
오류입니다.)
파이썬에서는 a = 2
저장된 모든 것에 아무 것도하지 않습니다 a
. 그것은 단지 2
지금 a
대신에 저장 된다는 것을 의미합니다 . (에 저장된 객체 가 없으면 a
괜찮습니다.)
궁극적으로 이것은 더 깊은 구별의 일부입니다.
C ++와 같은 언어의 변수는 메모리의 형식화 된 위치입니다. 경우 a
입니다 int
, 그 수단은 컴파일러가 해석하도록되어 알고있는 4 바이트 곳입니다 int
. 따라서 그렇게하면 a = 2
4 바이트의 메모리에 저장된 내용을 0, 0, 0, 1
에서0, 0, 0, 2
. 다른 곳에서 다른 int 변수가 있으면 자체 4 바이트가 있습니다.
파이썬과 같은 언어의 변수는 생명력이있는 객체의 이름입니다. 숫자에 대한 객체 1
와 숫자 에 대한 다른 객체가 2
있습니다. 그리고 a
로 표현되는 4 바이트의 메모리가 int
아니라 1
객체 를 가리키는 이름 일뿐 입니다. a = 2
숫자 1을 숫자 2로 바꾸는 것은 이치에 맞지 않습니다 (파이썬 프로그래머에게 우주의 기본 작업을 변화 시키기에는 너무 많은 힘을 줄 것입니다). 대신 객체를 a
잊어 버리고 1
객체를 가리 키십시오 2
.
할당이 돌연변이가 아닌 경우에 따라서, 무엇 이다 돌연변이는?
- 같은 돌연변이 문서화하는 방법을 호출
a.append(b)
. (이러한 메소드는 거의 항상을 반환None
합니다.) 불변 유형에는 그러한 메소드가 없으며 일반적으로 변경 가능한 유형이 있습니다. a.spam = b
또는 과 같이 객체의 일부에 할당a[0] = b
. 불변 유형은 속성 또는 요소에 대한 할당을 허용하지 않으며, 가변 유형은 일반적으로 둘 중 하나를 허용합니다.- 때로는과 같이 확장 된 할당을 사용하는
a += b
경우가 종종 있습니다. 가변 유형은 일반적으로 값을 변경합니다. 불변 유형은 절대로하지 않고 대신 사본을 제공합니다 (계산a + b
후 결과를에 할당a
).
그러나 할당이 돌연변이가 아닌 경우 객체 돌연변이의 일부에 할당하는 방법은 무엇입니까? 그것이 까다로워지는 곳입니다. a[0] = b
하지 아니 하는 mutate a[0]
(다시, C는 달리 ++),하지만 하지 의 mutate를a
간접적으로 제외하고 C ++과 달리 .
이 모든 것은 아마 더 나은 이유가 없습니다 당신이 사용하는 언어의 관점에서 파이썬의 의미를 넣어 시도하고 대신 자신의 조건에 파이썬의 의미를 배울 수 있습니다.
답변
객체가 변경 가능한지 여부는 유형에 따라 다릅니다. 이것은 특정 메소드가 있는지 여부 또는 클래스 계층 구조에 의존하지 않습니다.
사용자 정의 형식 (예 : 클래스)은 일반적으로 변경 가능합니다. 불변 유형의 단순한 서브 클래스와 같은 예외가 있습니다. 다른 불변의 유형에는 몇 가지 기본 유형과 같은 int
, float
, tuple
및str
뿐만 아니라 일부 파이썬 클래스 C로 구현 된,
“Python Language Reference”의 “Data Model”장에 대한 일반적인 설명 :
일부 개체의 값은 변경 될 수 있습니다. 값을 변경할 수있는 객체는 변경 가능하다고합니다. 일단 생성 된 값을 변경할 수없는 객체를 불변이라고합니다.
(변경 가능한 객체에 대한 참조가 포함 된 변경 불가능한 컨테이너 객체의 값은 후자의 값이 변경 될 때 변경 될 수 있지만, 포함 된 객체의 컬렉션을 변경할 수 없기 때문에 컨테이너는 여전히 불변으로 간주됩니다. 따라서 불변성은 엄격하지 않습니다. 변경 불가능한 값을 갖는 것과 동일하게 더 미묘합니다.)
객체의 가변성은 유형에 따라 결정됩니다. 예를 들어 숫자, 문자열 및 튜플은 변경할 수 없지만 사전과 목록은 변경할 수 있습니다.
답변
가변 객체와 불변 객체의 차이점
정의
가변 객체 : 생성 후 변경할 수있는 객체입니다.
불변 객체 : 생성 후 변경할 수없는 객체입니다.
파이썬에서는 불변 객체의 값을 변경하면 새로운 객체가 생성됩니다.
가변 객체
다음은 파이썬에서 변경 가능한 유형의 객체입니다.
list
Dictionary
Set
bytearray
user defined classes
불변 개체
다음은 불변 유형의 Python 객체입니다.
int
float
decimal
complex
bool
string
tuple
range
frozenset
bytes
답변되지 않은 질문
질문 : 문자열은 불변 유형입니까?
답 : 예 , 그러나 당신은 이것을 설명 할 수 있습니다 :
증명 1 :
a = "Hello"
a +=" World"
print a
산출
"Hello World"
위 예제에서 문자열은 “Hello”로 생성 된 후 “Hello World”로 변경되었습니다. 이는 문자열이 변경 가능한 유형임을 의미합니다. 그러나 변경 가능한 유형인지 여부를 확인하기 위해 ID를 확인할 때가 아닙니다.
a = "Hello"
identity_a = id(a)
a += " World"
new_identity_a = id(a)
if identity_a != new_identity_a:
print "String is Immutable"
산출
String is Immutable
증명 2 :
a = "Hello World"
a[0] = "M"
산출
TypeError 'str' object does not support item assignment
질문 : Tuple은 불변 타입입니까?
답 : 네 , 그렇습니다 .
증명 1 :
tuple_a = (1,)
tuple_a[0] = (2,)
print a
산출
'tuple' object does not support item assignment
