Python의 i += x 및 i = i + x 표현식이 동일한지 여부에 대한 자세한 설명

高洛峰
풀어 주다: 2017-02-10 09:11:35
원래의
1356명이 탐색했습니다.

이 글에서는 주로 i += x와 i = i + x 표현식이 Python에서 동일한지 여부에 대한 관련 정보를 예제 코드를 통해 자세히 소개하고 있습니다. 필요하신 친구들은 오셔서 아래 구경하시면 됩니다.

서문

최근에 아주 간단해 보이지만 사실 깊은 의미를 지닌 질문을 봤습니다. 그 질문은 i += x 와 i = 였습니다. i + x는 동일합니까? 대답이 '예'라면 축하합니다. 50% 맞습니다. 왜 절반만 맞다고 하시나요? 우리의 일반적인 이해에 따르면 정수 연산과 관련하여 둘 사이에는 유사점이나 차이점이 없지만 목록 연산에서도 동일합니까?

먼저 다음 두 코드를 살펴보세요.

코드 1

>>> l1 = range(3)
>>> l2 = l1
>>> l2 += [3]
>>> l1
[0, 1, 2, 3]
>>> l2
[0, 1, 2, 3]
로그인 후 복사

코드 2

>>> l1 = range(3)
>>> l2 = l1
>>> l2 = l2 + [3]
>>> l1
[0, 1, 2]
>>> l2
[0, 1, 2, 3]
로그인 후 복사

코드 1과 코드 2의 l2 값은 동일하지만 l1 값이 다르므로 i += x 및 i를 나타냅니다. = i + x 그것들은 동일하지 않습니다. 그러면 어떤 상황에서 동일하며 어떤 상황에서 동일하지 않습니까?

이 문제를 명확히 하기 전에 먼저 가변 객체와 불변 객체라는 두 가지 개념을 이해해야 합니다.

Python의 모든 객체에는 고유 식별자, 유형, 값이라는 세 가지 공통 속성이 있습니다.

고유 식별: 은 메모리에서 개체의 고유성을 식별하는 데 사용됩니다. 개체가 생성된 후에는 변경되지 않습니다.

유형의 고유 식별자: 는 개체가 지원하는 작업을 결정합니다. 예를 들어 목록은 길이 속성과 정수는 그렇지 않습니다. 마찬가지로, 객체의 유형이 결정되면 변경되지 않습니다. type() 함수는 객체의 유형 정보를 반환할 수 있습니다.

객체의 값은 고유 식별자와 다릅니다. 모든 객체 값이 변경 불가능한 것은 아닙니다. 일부 객체의 값은 특정 작업을 통해 변경될 수 있습니다. 변경 가능한 객체(mutable), 값을 변경할 수 없는 객체를 불변 객체(immutable)라고 합니다.

불변 객체(immutable)

불변 객체의 경우 값은 항상 처음 생성되었을 때의 값입니다. 객체에 대한 작업을 수행하면 새 객체가 생성됩니다.

>>> a = 1
>>> id(a)
32574568
>>> a += 1
>>> id(a)
32574544
로그인 후 복사

정수 "1"은 처음에 할당될 때 정수 개체 1을 가리키지만 += 연산이 수행됩니다. 변수 a 마지막으로, a는 또 다른 정수 객체 2를 가리키지만, 객체 1은 아무런 변화 없이 여전히 거기에 있고, 변수 a는 이미 새로운 객체 2를 가리킵니다. 일반적인 불변 객체에는 int, tuple, set, str이 포함됩니다.

详解Python中表达式i += x与i = i + x是否等价

가변 객체(mutable)

변경 가능한 객체의 값은 특정 작업을 통해 동적으로 변경될 수 있습니다. 예를 들어 목록 개체는 추가 메서드를 통해 목록에 요소를 지속적으로 추가할 수 있으며 목록의 값은 지속적으로 변경됩니다. 변수 개체가 두 변수에 할당되면 동일한 인스턴스 개체를 공유하고 동일한 메모리를 가리킵니다. 주소는 변수 중 하나를 조작할 때 다른 변수에도 영향을 미칩니다.

>>> x = range(3)
>>> y = x

>>> id(x)
139726103041232
>>> id(y)
139726103041232

>>> x.append(3)
>>> x
[0, 1, 2, 3]
>>> y
[0, 1, 2, 3]

>>> id(x)
139726103041232
>>> id(y)
139726103041232
로그인 후 복사

详解Python中表达式i += x与i = i + x是否等价

추가 작업을 수행한 후에도 객체의 메모리 주소는 변경되지 않으며 x와 y는 여전히 원래의 객체는 그 값이 변경되었다는 것뿐입니다.

详解Python中表达式i += x与i = i + x是否等价

가변 객체와 불변 객체를 이해하고 다시 질문 자체로 돌아가서 +=와 +의 차이점은 무엇인가요?

+= 작업은 먼저 개체의 __iadd__ 메서드를 호출하려고 시도합니다. 그런 메서드가 없으면 하자. 먼저 이것을 살펴보세요.

__add__와 __iadd__의 차이점

  1. __add__ 메서드는 두 개를 받습니다. 매개변수 값은 변경되지 않습니다.

  2. __iadd__ 메소드도 두 개의 매개변수를 받지만 이는 내부 작업입니다. 즉, 개체가 변수여야 하므로 첫 번째 매개변수의 값이 변경됩니다. 불변 객체에는 __iadd__ 메소드가 없습니다.

>>> hasattr(int, '__iadd__')
False
>>> hasattr(list, '__iadd__')
True
로그인 후 복사

분명히 정수 개체에는 __iadd__가 없지만 목록 개체는 __iadd__ 메서드를 제공합니다.

아아앙

代码1中的 += 操作调用的是__iadd__方法,他会原地修改l2指向的那个对象本身的值

详解Python中表达式i += x与i = i + x是否等价

>>> l2 = l2 + [3] # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
로그인 후 복사

而代码2中的 + 操作调用的是 __add__ 方法,该方法会返回一个新的对象,原来的对象保持不变,l1还是指向原来的对象,而l2已经指向一个新的对象。

详解Python中表达式i += x与i = i + x是否等价

以上就是表达式 i += x 与 i = i + x 的区别。因此对于列表进行 += 操作时,会存在潜在的bug,因为l1会因为l2的变化而发生改变,就像函数的参数不宜使用可变对象作为关键字参数一样。

更多详解Python中表达式i += x与i = i + x是否等价相关文章请关注PHP中文网!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿