>  기사  >  백엔드 개발  >  Python 표현식 i += x는 i = i + x와 동일합니까?

Python 표현식 i += x는 i = i + x와 동일합니까?

伊谢尔伦
伊谢尔伦원래의
2017-02-08 13:52:021201검색

파이썬 표현식 i += x는 i = i + x와 동일합니까? 대답이 '예'라면 축하합니다. 50% 맞습니다. 왜 절반만 맞다고 하시나요? 우리의 일반적인 이해에 따르면 정수 연산과 관련하여 둘 사이에는 유사점이나 차이점이 없지만 목록 연산에서도 동일합니까? 먼저 다음 두 코드를 살펴보세요.

Code 1

>>> l1 = range(3)
>>> l2 = l1
>>> l2 += [3]
>>> l1
[0, 1, 2, 3]
>>> l2
[0, 1, 2, 3]

Code 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의 모든 객체에는 고유 식별자, 유형, 값이라는 세 가지 공통 속성이 있습니다.

고유 식별: 메모리에서 객체의 고유성을 식별하는 데 사용됩니다. 객체가 생성된 후에는 변경되지 않습니다. id() 함수는 객체의 고유 식별을 볼 수 있습니다. 유형: 결정됨 객체가 지원하는 작업은 다릅니다. 예를 들어 목록에는 길이 속성이 있을 수 있지만 정수는 그렇지 않습니다. 마찬가지로, 객체의 유형이 결정되면 변경되지 않습니다. type() 함수는 객체의 유형 정보를 반환할 수 있습니다.

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

불변 객체(immutable)

불변 객체의 경우 값은 항상 , 이 개체에 대한 작업을 수행하면 새 개체가 생성됩니다.

>>> a = 1
>>> id(a)
32574568
>>> a += 1
>>> id(a)
32574544

정수 "1"은 불변 객체입니다. 처음에 a는 정수 객체 1을 가리키지만, 변수 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와 동일합니까?+= 작업은 먼저 객체의 __iadd__ 메서드를 호출하려고 시도합니다. 그런 메서드가 없으면 __add__ 메서드를 호출해 보겠습니다.

__add__와 __iadd__의 차이점은 무엇입니까?

__add__ 메서드는 두 개의 매개변수를 받고 그 합계를 반환합니다. 두 매개변수의 값은 변경되지 않습니다.

__iadd__ 메소드도 두 개의 매개변수를 받지만 이는 내부 작업입니다. 즉, 첫 번째 매개변수의 값을 변경한다는 의미입니다. 왜냐하면 객체가 변경 가능해야 하므로 불변이 필요하지 않기 때문입니다. 객체 __iadd__ 메소드.

>>> hasattr(int, '__iadd__')
False
>>> hasattr(list, '__iadd__')
True

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

>>> l2 += [3]  # 代码1:使用__iadd__,l2的值原地修改

코드 1의 += 연산은 __iadd__ 메서드를 호출하여 l2가 가리키는 객체의 값을 제자리에서 수정합니다.

>>> l2 = l2 + [3]  # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
Python 표현식 i += x는 i = i + x와 동일합니까?The + 코드 2의 연산은 새 개체를 반환하는 __add__ 메서드를 호출합니다. 원래 개체는 변경되지 않고 그대로 유지되며 l2는 이미 새 개체를 가리킵니다.

Python 표현식 i += x는 i = i + x와 동일합니까?

위는 i += x와 i = i + x라는 표현의 차이점입니다. 따라서 목록에서 += 작업을 수행할 때 잠재적인 버그가 있을 수 있습니다. 왜냐하면 함수의 매개변수가 변수 개체를 키워드 매개변수로 사용해서는 안 되는 것처럼 l1이 l2의 변경으로 인해 변경되기 때문입니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:파이썬 고급 사전다음 기사:파이썬 고급 사전