CPython에서 -5 ~ 256 사이의 값을 가지는 정수타입 객체

CPython에서는 흥미로운 사실이 발견된다.

변수에 값을 대입하는 흔한 식 a = 1 에서 = 연산자는 1이라는 값을 a에다가 할당하겠다는 뜻이다.

이것은 1이라는 값을 가진 a라는 객체를 생성하겠다는 뜻과 같다.


1
2
3
4
5
6
7
8
9
10
>>> id(5)
10914624

>>> a = 5
>>> id(a)
10914624

>>> b = 3 + 2
>>> id(b)
10914624

위의 코드에서 5라는 정수는 10914624 라는 객체 id를 가지고 있다.

하지만 a와 b 변수에 5라는 값을 할당했는데도 새로운 객체가 생성된 것이 아닌 같은 id를 가지게 된다.


https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong

docs에 따르면 CPython 내부 메모리에는 -5 ~ 256 사이의 정수 값에 해당하는 객체가 미리 생성되어 있다.

이 범위의 값을 새로운 변수에 할당하게 될 때,

새로 객체를 생성하는 것이 아니라 미리 생성된 객체를 참조하게 된다.

그래서 위의 예제와 같은 일이 일어나게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> a = 5
>>> a is 5
True
>>> id(a)
10914624
>>> id(5)
10914624

>>> a = 257
>>> a is 257
False
>>> id(a)
139848341129200
>>> id(257)
139848341128016

범위를 벗어난 257의 객체 id는

1
139848341128016

257이란 값을 a라는 변수에 할당했을 때 a 객체의 id는

1
139848341129200

두 객체의 id가 다른것을 확인할 수 있다.

즉 범위를 벗어난 정수값을 새로운 변수에 할당했을 때에만 새로운 객체를 생성한다는 것이다.


1
a is b

is 연산자는 a와 b 값을 비교하는 것이 아닌, 서로 같은 객체인지를 판별한다.

1
a == b

만약 같은 값을 비교하고 싶다면\== 연산자를 사용하여 값을 비교할 수 있다.

1
2
3
4
5
>>> a = 257
>>> a is 257
False
>>> a == 257
True

따라서 -5 ~ 256 범위의 int형 정수를 비교할 때는 is 연산자와 == 연산자 사용에 주의를 기울일 필요가 있다.

CPython에서 -5 ~ 256 사이의 값을 가지는 정수타입 객체

https://l-yohai.github.io/CPython-integer-object/

Author

Yohan Lee

Posted on

2020-05-30

Updated on

2021-08-22

Licensed under

댓글