μΉ΄ν…Œκ³ λ¦¬ 보관물: Python

Python

β€œisβ€μ—°μ‚°μžλŠ” μ •μˆ˜λ‘œ 예기치 μ•Šκ²Œ λ™μž‘ν•©λ‹ˆλ‹€

μ™œ νŒŒμ΄μ¬μ—μ„œ λ‹€μŒμ΄ 예기치 μ•Šκ²Œ λ™μž‘ν•©λ‹ˆκΉŒ?

>>> a = 256
>>> b = 256
>>> a is b
True           # This is an expected result
>>> a = 257
>>> b = 257
>>> a is b
False          # What happened here? Why is this False?
>>> 257 is 257
True           # Yet the literal numbers compare properly

Python 2.5.2λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ λ²„μ „μ˜ Python을 μ‹œλ„ν•΄ 보면 Python 2.3.3은 99와 100 μ‚¬μ΄μ˜ μœ„μ˜ λ™μž‘μ„ λ³΄μ—¬μ€λ‹ˆλ‹€.

μœ„μ˜ λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ 파이썬이 λ‚΄λΆ€μ μœΌλ‘œ κ΅¬ν˜„λ˜μ–΄ β€œμž‘μ€β€μ •μˆ˜κ°€ 큰 μ •μˆ˜μ™€ λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ μ €μž₯되고 isμ—°μ‚°μžκ°€ κ·Έ 차이λ₯Ό μ•Œ 수 μžˆλ‹€κ³  κ°€μ • ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ™œ μƒˆλŠ” 좔상화인가? 두 개의 μž„μ˜μ˜ 객체λ₯Ό λΉ„κ΅ν•˜μ—¬ μˆ«μžμΈμ§€ μ—¬λΆ€λ₯Ό 미리 μ•Œ μˆ˜μ—†λŠ” 경우 λ™μΌν•œ μ§€ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” 더 쒋은 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?



λ‹΅λ³€

이것 μ’€ 봐 :

>>> a = 256
>>> b = 256
>>> id(a)
9987148
>>> id(b)
9987148
>>> a = 257
>>> b = 257
>>> id(a)
11662816
>>> id(b)
11662828

λ‹€μŒμ€ Python 2 λ¬Έμ„œ β€œPlain Integer Objects” μ—μ„œ 찾은 λ‚΄μš©μž…λ‹ˆλ‹€ ( Python 3 κ³Ό 동일 ).

ν˜„μž¬ κ΅¬ν˜„μ—μ„œλŠ” -5와 256 μ‚¬μ΄μ˜ λͺ¨λ“  μ •μˆ˜μ— λŒ€ν•΄ μ •μˆ˜ 객체 배열을 μœ μ§€ν•©λ‹ˆλ‹€.이 λ²”μœ„μ—μ„œ intλ₯Ό λ§Œλ“€λ©΄ μ‹€μ œλ‘œλŠ” κΈ°μ‘΄ 객체에 λŒ€ν•œ μ°Έμ‘°λ₯Ό λ‹€μ‹œ μ–»μŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 1의 값을 λ³€κ²½ν•  수 μžˆμ–΄μ•Όν•©λ‹ˆλ‹€.이 경우 Python의 λ™μž‘μ΄ μ •μ˜λ˜μ§€ μ•Šμ€ 것 κ°™μŠ΅λ‹ˆλ‹€. πŸ™‚


λ‹΅λ³€

파이썬의 β€œisβ€μ—°μ‚°μžλŠ” μ •μˆ˜λ‘œ 예기치 μ•Šκ²Œ λ™μž‘ν•©λ‹ˆκΉŒ?

μš”μ•½ν•˜μžλ©΄ λ‹€μŒκ³Ό 같이 κ°•μ‘°ν•˜κ² μŠ΅λ‹ˆλ‹€ . μ •μˆ˜λ₯Ό 비ꡐ ν•˜λŠ” is데 μ‚¬μš©ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€ .

이것은 당신이 κΈ°λŒ€ν•΄μ•Ό ν•  행동이 μ•„λ‹™λ‹ˆλ‹€.

λŒ€μ‹ , μ‚¬μš© ==및 !=각각 평등과 λΆˆν‰λ“±μ— λŒ€ν•œ 비ꡐ. 예λ₯Ό λ“€λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

>>> a = 1000
>>> a == 1000       # Test integers like this,
True
>>> a != 5000       # or this!
True
>>> a is 1000       # Don't do this! - Don't use `is` to test integers!!
False

μ„€λͺ…

이것을 μ•ŒκΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒμ„ μ•Œμ•„μ•Όν•©λ‹ˆλ‹€.

첫째, 무엇을 isν•©λ‹ˆκΉŒ? 비ꡐ μ—°μ‚°μžμž…λ‹ˆλ‹€. λ‘œλΆ€ν„° λ¬Έμ„œ :

x와 yκ°€ λ™μΌν•œ 객체 인 κ²½μš°μ—λ§Œ μ—°μ‚°μž is및 is not객체 동일성 ν…ŒμŠ€νŠΈ : x is ytrueμž…λ‹ˆλ‹€. x is not yμ—­ 진리 값을 μ‚°μΆœν•©λ‹ˆλ‹€.

λ”°λΌμ„œ λ‹€μŒμ€ λ™μΌν•©λ‹ˆλ‹€.

>>> a is b
>>> id(a) == id(b)

λ‘œλΆ€ν„° λ¬Έμ„œ :

id
객체의 β€œμ •μ²΄μ„±β€μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€. 이것은 수λͺ… λ™μ•ˆμ΄ κ°œμ²΄μ— λŒ€ν•΄ κ³ μœ ν•˜κ³  μΌμ •ν•˜κ²Œ 보μž₯λ˜λŠ” μ •μˆ˜ (λ˜λŠ” κΈ΄ μ •μˆ˜)μž…λ‹ˆλ‹€. κ²ΉμΉ˜μ§€ μ•ŠλŠ” 수λͺ…을 κ°€μ§„ 두 개체의 id()κ°’ 이 동일 ν•  수 μžˆμŠ΅λ‹ˆλ‹€ .

CPythonμ—μ„œ 객체의 id (Python의 μ°Έμ‘° κ΅¬ν˜„)κ°€ λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜λΌλŠ” 사싀은 κ΅¬ν˜„ μ„ΈλΆ€ μ‚¬ν•­μž…λ‹ˆλ‹€. λ‹€λ₯Έ Python κ΅¬ν˜„ (예 : Jython λ˜λŠ” IronPython)은에 λŒ€ν•΄ λ‹€λ₯Έ κ΅¬ν˜„μ„ μ‰½κ²Œ κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€ id.

κ·Έλ ‡λ‹€λ©΄ 유슀 μΌ€μ΄μŠ€λŠ” isλ¬΄μ—‡μž…λ‹ˆκΉŒ? PEP8은 λ‹€μŒμ„ μ„€λͺ…ν•©λ‹ˆλ‹€ .

μ‹±κΈ€ ν†€κ³Όμ˜ 비ꡐ NoneλŠ” 항상 λ“±ν˜Έ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³  isλ˜λŠ”
둜 μˆ˜ν–‰ν•΄μ•Όν•©λ‹ˆλ‹€ is not.

질문

λ‹€μŒ μ§ˆλ¬Έμ„ 묻고 μ§„μˆ ν•˜μ‹­μ‹œμ˜€ (μ½”λ“œ 포함).

μ™œ νŒŒμ΄μ¬μ—μ„œ λ‹€μŒμ΄ 예기치 μ•Šκ²Œ λ™μž‘ν•©λ‹ˆκΉŒ?

>>> a = 256
>>> b = 256
>>> a is b
True           # This is an expected result

μ˜ˆμƒ 된 κ²°κ³Ό κ°€ μ•„λ‹™λ‹ˆλ‹€ . μ™œ μ˜ˆμƒλ©λ‹ˆκΉŒ? 그것은 단지 κ°€μΉ˜ μ •μˆ˜λŠ” 것을 의미 256λͺ¨λ‘μ— μ˜ν•΄ μ°Έμ‘° a및 bμ •μˆ˜μ˜ λ™μΌν•œ μΈμŠ€ν„΄μŠ€μž…λ‹ˆλ‹€. μ •μˆ˜λŠ” νŒŒμ΄μ¬μ—μ„œ λ³€κ²½ν•  수 μ—†μœΌλ―€λ‘œ λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 이것은 μ½”λ“œμ— 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ˜ˆμƒν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. 그것은 단지 κ΅¬ν˜„ μ„ΈλΆ€ μ‚¬ν•­μž…λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μš°λ¦¬λŠ” 256μ΄λΌλŠ” 값을 말할 λ•Œλ§ˆλ‹€ λ©”λͺ¨λ¦¬μ— μƒˆλ‘œμš΄ λ³„λ„μ˜ μΈμŠ€ν„΄μŠ€κ°€ μ—†λ‹€λŠ” 것을 기뻐해야 ν•  κ²ƒμž…λ‹ˆλ‹€.

>>> a = 257
>>> b = 257
>>> a is b
False          # What happened here? Why is this False?

257λ©”λͺ¨λ¦¬μ— 값이 μžˆλŠ” 두 개의 μ •μˆ˜ μΈμŠ€ν„΄μŠ€κ°€μžˆλŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€ . μ •μˆ˜λŠ” λΆˆλ³€μ΄λ―€λ‘œ λ©”λͺ¨λ¦¬κ°€ λ‚­λΉ„λ©λ‹ˆλ‹€. μš°λ¦¬κ°€ 많이 λ‚­λΉ„ν•˜μ§€ μ•ŠκΈ°λ₯Ό λ°”λžλ‹ˆλ‹€. μš°λ¦¬λŠ” μ•„λ§ˆ 아닐 κ²ƒμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜μ΄ λ™μž‘μ€ 보μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

>>> 257 is 257
True           # Yet the literal numbers compare properly

κΈ€μŽ„, 이것은 파이썬의 νŠΉμ • κ΅¬ν˜„μ΄ λ˜‘λ˜‘ν•˜κ³  λ…Έλ ₯ν•˜μ§€ μ•ŠλŠ” ν•œ λ©”λͺ¨λ¦¬μ— 쀑볡 값을 μƒμ„±ν•˜μ§€ μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. CPython 인 Python의 μ°Έμ‘° κ΅¬ν˜„μ„ μ‚¬μš©ν•˜κ³  μžˆμŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€. CPython에 μ’‹μŠ΅λ‹ˆλ‹€.

CPython이 μ „ 세계적 으둜이 μž‘μ—…μ„ μˆ˜ν–‰ ν•  수 μžˆλ‹€λ©΄ 더 μ €λ ΄ ν•  수 μžˆλ‹€λ©΄ (검색 λΉ„μš©μ΄ λ“€κΈ° λ•Œλ¬Έμ—) μ•„λ§ˆλ„ λ‹€λ₯Έ κ΅¬ν˜„ 일 수 μžˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μ½”λ“œμ— λ―ΈμΉ˜λŠ” 영ν–₯에 λŒ€ν•΄μ„œλŠ” μ •μˆ˜κ°€ μ •μˆ˜μ˜ νŠΉμ • μΈμŠ€ν„΄μŠ€μΈμ§€λŠ” μ‹ κ²½ μ“°μ§€ μ•Šμ•„μ•Όν•©λ‹ˆλ‹€. ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€μ˜ 값이 무엇인지 μ‹ κ²½ μ¨μ•Όν•˜λ©°, 이에 λŒ€ν•œ 일반 비ꡐ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€ (예 πŸ™‚ ==.

무엇 isν•©λ‹ˆκΉŒ

isκ²€μ‚¬λŠ” 것을 id두 κ°μ²΄λŠ” λ™μΌν•˜λ‹€. CPythonμ—μ„œμ΄ idμœ„μΉ˜λŠ” λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜μ΄μ§€λ§Œ λ‹€λ₯Έ κ΅¬ν˜„μ—μ„œ λ‹€λ₯Έ 고유 번호 일 수 μžˆμŠ΅λ‹ˆλ‹€. 이것을 μ½”λ“œλ‘œ λ°”κΎΈλ €λ©΄ :

>>> a is b

와 κ°™λ‹€

>>> id(a) == id(b)

μ™œ μš°λ¦¬κ°€ μ‚¬μš©ν•˜κ³  μ‹Ά isμŠ΅λ‹ˆκΉŒ?

이것은 두 개의 맀우 κΈ΄ λ¬Έμžμ—΄μ˜ 값이 같은지 ν™•μΈν•˜λŠ” 것과 λΉ„κ΅ν•˜μ—¬ 맀우 λΉ λ₯Έ 검사 일 수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 객체의 κ³ μœ μ„±μ— μ μš©λ˜λ―€λ‘œ μ‚¬μš© 사둀가 μ œν•œμ μž…λ‹ˆλ‹€. μ‹€μ œλ‘œ μš°λ¦¬λŠ” 주둜 Noneμ‹±κΈ€ 톀 (λ©”λͺ¨λ¦¬μ˜ ν•œ 곳에 μ‘΄μž¬ν•˜λŠ” μœ μΌν•œ μΈμŠ€ν„΄μŠ€) 인 확인에 μ‚¬μš©ν•˜λ €κ³ ν•©λ‹ˆλ‹€ . μ„œλ‘œ ν˜Όλ™ ν•  κ°€λŠ₯μ„±μ΄μžˆλŠ” 경우 λ‹€λ₯Έ μ‹±κΈ€ 톀을 λ§Œλ“€ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€ is. λ‹€μŒμ€ μ˜ˆμ œμž…λ‹ˆλ‹€ (Python 2 및 3μ—μ„œ μž‘λ™). 예 :

SENTINEL_SINGLETON = object() # this will only be created one time.

def foo(keyword_argument=None):
    if keyword_argument is None:
        print('no argument given to foo')
    bar()
    bar(keyword_argument)
    bar('baz')

def bar(keyword_argument=SENTINEL_SINGLETON):
    # SENTINEL_SINGLETON tells us if we were not passed anything
    # as None is a legitimate potential argument we could get.
    if keyword_argument is SENTINEL_SINGLETON:
        print('no argument given to bar')
    else:
        print('argument to bar: {0}'.format(keyword_argument))

foo()

μ–΄λ–€ μ§€λ¬Έ :

no argument given to foo
no argument given to bar
argument to bar: None
argument to bar: baz

λ”°λΌμ„œ is센티넬을 μ‚¬μš©ν•˜λ©΄ barμΈμˆ˜μ—†μ΄ 호좜 ν•  λ•Œ 와 호좜 ν•  λ•Œλ₯Ό ꡬ뢄할 수 NoneμžˆμŠ΅λ‹ˆλ‹€. 이것듀은 μ£Όμš” 유슀 μΌ€μ΄μŠ€μž…λ‹ˆλ‹€ is– μ •μˆ˜, λ¬Έμžμ—΄, νŠœν”Œ λ˜λŠ” 이와 같은 λ‹€λ₯Έ κ²ƒλ“€μ˜ 동등성을 ν…ŒμŠ€νŠΈν•˜λŠ” 데 μ‚¬μš© ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€ .


λ‹΅λ³€

두 κ°€μ§€κ°€ λ™μΌν•œ μ§€ λ˜λŠ” λ™μΌν•œ 객체인지 여뢀에 따라 λ‹€λ¦…λ‹ˆλ‹€.

isλ™μΌν•œ 객체가 μ•„λ‹Œ λ™μΌν•œ 객체인지 ν™•μΈν•©λ‹ˆλ‹€. μž‘μ€ μ •μˆ˜λŠ” μ•„λ§ˆλ„ 곡간 νš¨μœ¨μ„±μ„ μœ„ν•΄ λ™μΌν•œ λ©”λͺ¨λ¦¬ μœ„μΉ˜λ₯Ό 가리킀고 μžˆμŠ΅λ‹ˆλ‹€.

In [29]: a = 3
In [30]: b = 3
In [31]: id(a)
Out[31]: 500729144
In [32]: id(b)
Out[32]: 500729144

==μž„μ˜ 객체의 동등성을 비ꡐ ν•˜λŠ” 데 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. __eq__및 __ne__속성을 μ‚¬μš©ν•˜μ—¬ λ™μž‘μ„ μ§€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€ .


λ‹΅λ³€

λŠ¦μ—ˆμ§€λ§Œ λ‹΅λ³€μ΄μžˆλŠ” μ†ŒμŠ€λ₯Ό μ›ν•˜μ‹­λ‹ˆκΉŒ? 더 λ§Žμ€ μ‚¬λžŒλ“€μ΄ 따라 ν•  수 μžˆλ„λ‘ μž…λ¬Έ λ°©μ‹μœΌλ‘œ μ‹œλ„ν•˜κ³  λ§ν•˜κ² μŠ΅λ‹ˆλ‹€.


CPython의 쒋은 점은 μ‹€μ œλ‘œ μ†ŒμŠ€λ₯Ό λ³Ό 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 3.5 λ¦΄λ¦¬μŠ€μ—λŠ” 링크λ₯Ό μ‚¬μš© ν•˜μ§€λ§Œ ν•΄λ‹Ή 2.x 링크λ₯Ό μ°ΎλŠ” 것은 쉽지 μ•ŠμŠ΅λ‹ˆλ‹€.

CPythonμ—μ„œ μƒˆ 였브젝트 μž‘μ„±μ„ 처리 ν•˜λŠ” C-API ν•¨μˆ˜ intλŠ” PyLong_FromLong(long v)μž…λ‹ˆλ‹€. 이 κΈ°λŠ₯에 λŒ€ν•œ μ„€λͺ…은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

ν˜„μž¬ κ΅¬ν˜„μ€ -5μ—μ„œ 256 μ‚¬μ΄μ˜ λͺ¨λ“  μ •μˆ˜μ— λŒ€ν•΄ μ •μˆ˜ 객체 배열을 μœ μ§€ν•©λ‹ˆλ‹€.이 λ²”μœ„μ—μ„œ intλ₯Ό λ§Œλ“€λ©΄ μ‹€μ œλ‘œλŠ” κΈ°μ‘΄ 객체에 λŒ€ν•œ μ°Έμ‘°λ₯Ό λ‹€μ‹œ μ–»μŠ΅λ‹ˆλ‹€ . λ”°λΌμ„œ 1의 값을 λ³€κ²½ν•  수 μžˆμ–΄μ•Όν•©λ‹ˆλ‹€.이 경우 Python의 λ™μž‘μ΄ μ •μ˜λ˜μ§€ μ•Šμ€ 것 κ°™μŠ΅λ‹ˆλ‹€. πŸ™‚

(λ‚΄ 이타릭체)

당신에 λŒ€ν•΄ λͺ¨λ₯΄μ§€λ§Œ λ‚˜λŠ” 이것을보고 μƒκ°ν•©λ‹ˆλ‹€ : κ·Έ 배열을 μ°Ύμ•„ λ΄…μ‹œλ‹€!

CPython 을 κ΅¬ν˜„ν•˜λŠ” C μ½”λ“œλ₯Ό 닀루지 μ•Šμ•˜λ‹€λ©΄ ; λͺ¨λ“  것이 κ½€ 체계적이고 읽기 μ‰½μŠ΅λ‹ˆλ‹€. 우리의 경우, μš°λ¦¬λŠ”μ—μ„œ λ³Ό ν•„μš”κ°€ Objectsν•˜μœ„ 디렉토리 의 μ£Όμš” μ†ŒμŠ€ μ½”λ“œ 디렉토리 트리 .

PyLong_FromLonglong객체λ₯Ό 닀루 λ―€λ‘œ λ‚΄λΆ€λ₯Ό λ“€μ—¬λ‹€ λ³Ό ν•„μš”κ°€ μžˆλ‹€κ³  μΆ”λ‘ ν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€ longobject.c. λ‚΄λΆ€λ₯Ό μ‚΄νŽ΄λ³Έ ν›„ 상황이 ν˜Όλž€ μŠ€λŸ½λ‹€κ³  생각할 수 μžˆμŠ΅λ‹ˆλ‹€. 그듀은 μš°λ¦¬κ°€ μ°Ύκ³ μžˆλŠ” κΈ°λŠ₯이 230 번 쀄 μ—μ„œ μ°¨κ°€μ›Œ μ Έμ„œ μš°λ¦¬κ°€ 체크 μ•„μ›ƒν•˜κΈ°λ₯Ό 기닀리고 μžˆμŠ΅λ‹ˆλ‹€. μž‘μ€ κΈ°λŠ₯μ΄λ―€λ‘œ 본체 (μ„ μ–Έ μ œμ™Έ)λ₯Ό μ‰½κ²Œ λΆ™μ—¬ 넣을 수 μžˆμŠ΅λ‹ˆλ‹€.

PyObject *
PyLong_FromLong(long ival)
{
    // omitting declarations

    CHECK_SMALL_INT(ival);

    if (ival < 0) {
        /* negate: cant write this as abs_ival = -ival since that
           invokes undefined behaviour when ival is LONG_MIN */
        abs_ival = 0U-(unsigned long)ival;
        sign = -1;
    }
    else {
        abs_ival = (unsigned long)ival;
    }

    /* Fast path for single-digit ints */
    if (!(abs_ival >> PyLong_SHIFT)) {
        v = _PyLong_New(1);
        if (v) {
            Py_SIZE(v) = sign;
            v->ob_digit[0] = Py_SAFE_DOWNCAST(
                abs_ival, unsigned long, digit);
        }
        return (PyObject*)v;
}

이제 μš°λ¦¬λŠ” C master-code-haxxorz λŠ” μ•„λ‹ˆμ§€λ§Œ λ©μ²­ν•˜μ§€λ„ μ•ŠμŠ΅λ‹ˆλ‹€ CHECK_SMALL_INT(ival);. μš°λ¦¬λŠ” 이것이 이와 관련이 μžˆλ‹€λŠ” 것을 이해할 수 μžˆμŠ΅λ‹ˆλ‹€. 확인 ν•΄λ³΄μž:

#define CHECK_SMALL_INT(ival) \
    do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \
        return get_small_int((sdigit)ival); \
    } while(0)

λ”°λΌμ„œ get_small_intκ°’ ival이 쑰건을 λ§Œμ‘±ν•˜λ©΄ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” λ§€ν¬λ‘œμž…λ‹ˆλ‹€ .

if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS)

κ·Έλž˜μ„œ 무엇 NSMALLNEGINTSκ³Ό NSMALLPOSINTS? 맀크둜! μ—¬κΈ° μžˆμŠ΅λ‹ˆλ‹€ :

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif

우리의 μƒνƒœλŠ” if (-5 <= ival && ival < 257)call get_small_intμž…λ‹ˆλ‹€.

λ‹€μŒ get_small_int으둜 λͺ¨λ“  μ˜κ΄‘μ„ 보자 (자, μš°λ¦¬λŠ” 단지 ν₯미둜운 κ²ƒλ“€μ΄μžˆλŠ” 곳이기 λ•Œλ¬Έμ— λͺΈμ„ λ³Ό κ²ƒμž…λ‹ˆλ‹€) :

PyObject *v;
assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS);
v = (PyObject *)&small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);

자, aλ₯Ό μ„ μ–Έ PyObjectν•˜κ³  이전 쑰건이 μœ μ§€λ˜κ³  할당을 μ‹€ν–‰ν•œλ‹€κ³  μ£Όμž₯ν•˜μ‹­μ‹œμ˜€.

v = (PyObject *)&small_ints[ival + NSMALLNEGINTS];

small_intsμš°λ¦¬κ°€ μ°Ύκ³ μžˆλŠ” λ°°μ—΄κ³Ό 맀우 λΉ„μŠ·ν•©λ‹ˆλ‹€. μš°λ¦¬λŠ” 방금 λ¬Έμ„œλ₯Ό 읽을 수 μžˆμ—ˆκ³  λͺ¨λ“  것을 μ•Œμ•˜μ„ κ²ƒμž…λ‹ˆλ‹€! :

/* Small integers are preallocated in this array so that they
   can be shared.
   The integers that are preallocated are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS];

그래,이 μ‚¬λžŒμ€ 우리 λ‚¨μž μ•Ό intλ²”μœ„μ—μ„œ μƒˆ ν•­λͺ©μ„ λ§Œλ“€λ €λ©΄ [NSMALLNEGINTS, NSMALLPOSINTS)이미 ν• λ‹Ή 된 κΈ°μ‘΄ κ°œμ²΄μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό λ‹€μ‹œ κ°€μ Έμ˜΅λ‹ˆλ‹€.

μ°Έμ‘°λŠ” λ™μΌν•œ 객체λ₯Ό μ°Έμ‘°ν•˜λ―€λ‘œ id()직접 λ°œν–‰ ν•˜κ±°λ‚˜ IDλ₯Ό 확인 isν•˜λ©΄ μ •ν™•νžˆ λ™μΌν•œ κ²°κ³Όκ°€ λ°˜ν™˜λ©λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μ–Έμ œ ν• λ‹Ήλ©λ‹ˆκΉŒ?

_PyLong_Init파이썬 μ—μ„œ μ΄ˆκΈ°ν™”ν•˜λŠ” λ™μ•ˆ 기꺼이 for 루프에 λ“€μ–΄κ°€λ©΄ λ‹€μŒκ³Ό κ°™μ΄ν•˜μ‹­μ‹œμ˜€.

for (ival = -NSMALLNEGINTS; ival <  NSMALLPOSINTS; ival++, v++) {

루프 λ°”λ””λ₯Ό 읽으렀면 μ†ŒμŠ€λ₯Ό ν™•μΈν•˜μ‹­μ‹œμ˜€!

λ‚΄ μ„€λͺ…μœΌλ‘œ C 물건을 λͺ…ν™•ν•˜κ²Œ λ§Œλ“€μ—ˆ κΈ°λ₯Ό λ°”λžλ‹ˆλ‹€.


κ·ΈλŸ¬λ‚˜ 257 is 257? 뭐야?

이것은 μ‹€μ œλ‘œ μ„€λͺ…ν•˜κΈ°κ°€ 더 μ‰¬μš° λ©° 이미 κ·Έλ ‡κ²Œ μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€ . 파이썬 이이 λŒ€ν™” ν˜• 문을 단일 λΈ”λ‘μœΌλ‘œ μ‹€ν–‰ν•œλ‹€λŠ” 사싀 λ•Œλ¬Έμž…λ‹ˆλ‹€.

>>> 257 is 257

이 λ¬Έμž₯을 μ™„μ„±ν•˜λŠ” λ™μ•ˆ CPython은 두 개의 μΌμΉ˜ν•˜λŠ” λ¦¬ν„°λŸ΄μ΄ 있으며 λ™μΌν•œ PyLongObjectν‘œν˜„ 을 μ‚¬μš©ν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€ 257. μ»΄νŒŒμΌμ„ 직접 μˆ˜ν–‰ν•˜κ³  λ‚΄μš©μ„ κ²€μ‚¬ν•˜λ©΄ 이것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

>>> codeObj = compile("257 is 257", "blah!", "exec")
>>> codeObj.co_consts
(257, None)

CPython이 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ©΄ 이제 μ •ν™•νžˆ λ™μΌν•œ 객체λ₯Όλ‘œλ“œν•©λ‹ˆλ‹€.

>>> import dis
>>> dis.dis(codeObj)
  1           0 LOAD_CONST               0 (257)   # dis
              3 LOAD_CONST               0 (257)   # dis again
              6 COMPARE_OP               8 (is)

κ·Έλž˜μ„œ isλŒμ•„κ°‘λ‹ˆλ‹€ True.


λ‹΅λ³€

μ†ŒμŠ€ 파일 intobject.cλ₯Ό 체크인 ν•  수 μžˆμœΌλ―€λ‘œ , νŒŒμ΄μ¬μ€ νš¨μœ¨μ„±μ„ μœ„ν•΄ μž‘μ€ μ •μˆ˜λ₯Ό μΊμ‹œν•©λ‹ˆλ‹€. μž‘μ€ μ •μˆ˜μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό λ§Œλ“€ λ•Œλ§ˆλ‹€ μƒˆ 객체가 μ•„λ‹Œ μΊμ‹œ 된 μž‘μ€ μ •μˆ˜λ₯Ό μ°Έμ‘°ν•©λ‹ˆλ‹€. 257은 μž‘μ€ μ •μˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ λ‹€λ₯Έ 객체둜 κ³„μ‚°λ©λ‹ˆλ‹€.

==κ·Έ λͺ©μ  으둜 μ‚¬μš© ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.


λ‹΅λ³€

λ‚˜λŠ” λ‹Ήμ‹ μ˜ 가섀이 λ§žλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. id(객체의 동일성)으둜 μ‹€ν—˜ :

In [1]: id(255)
Out[1]: 146349024

In [2]: id(255)
Out[2]: 146349024

In [3]: id(257)
Out[3]: 146802752

In [4]: id(257)
Out[4]: 148993740

In [5]: a=255

In [6]: b=255

In [7]: c=257

In [8]: d=257

In [9]: id(a), id(b), id(c), id(d)
Out[9]: (146349024, 146349024, 146783024, 146804020)

숫자 <= 255λŠ” λ¦¬ν„°λŸ΄λ‘œ μ·¨κΈ‰λ˜λ©° μœ„μ˜ λ‚΄μš©μ€ λ‹€λ₯΄κ²Œ μ·¨κΈ‰λ©λ‹ˆλ‹€!


λ‹΅λ³€

μ •μˆ˜, λ¬Έμžμ—΄ λ˜λŠ” λ‚ μ§œ μ‹œκ°„κ³Ό 같은 λ³€κ²½ λΆˆκ°€λŠ₯ν•œ κ°’ 객체의 경우 객체 IDκ°€ 특히 μœ μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 평등에 λŒ€ν•΄ μƒκ°ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μ•„μ΄λ΄ν‹°ν‹°λŠ” 본질적으둜 κ°€μΉ˜ 객체에 λŒ€ν•œ κ΅¬ν˜„ μ„ΈλΆ€ μ‚¬ν•­μž…λ‹ˆλ‹€. λΆˆλ³€μ΄κΈ° λ•Œλ¬Έμ— λ™μΌν•œ 객체 λ˜λŠ” μ—¬λŸ¬ 객체에 λŒ€ν•œ 닀쀑 μ°Έμ‘°λ₯Ό κ°–λŠ” 것 μ‚¬μ΄μ—λŠ” 효과적인 차이가 μ—†μŠ΅λ‹ˆλ‹€.


이 글은 Python μΉ΄ν…Œκ³ λ¦¬λ‘œ λΆ„λ₯˜λ˜μ—ˆκ³  λ‹˜μ— μ˜ν•΄ 에 μž‘μ„±λμŠ΅λ‹ˆλ‹€.