# `dis` — 파이썬 바이트 코드 역 어셈블러

소스 코드: Lib/dis.py

`dis` 모듈은 CPython 바이트 코드를 역 어셈블 하여 분석을 지원합니다. 이 모듈이 입력으로 취하는 CPython 바이트 코드는 파일 `Include/opcode.h`에 정의되어 있으며 컴파일러와 인터프리터에서 사용됩니다.

CPython implementation detail: 바이트 코드는 CPython 인터프리터의 구현 세부 사항입니다. 파이썬 버전 간에 바이트 코드가 추가, 제거 또는 변경되지 않을 것이라는 보장은 없습니다. 이 모듈을 사용하는 것이 파이썬 VM이나 파이썬 릴리스에 걸쳐 작동할 것으로 생각하지 말아야 합니다.

버전 3.6에서 변경: 명령어마다 2바이트를 사용합니다. 이전에는 바이트 수가 명령어에 따라 달랐습니다.

예: 주어진 함수 `myfunc()`에 대해:

    def myfunc(alist):
        return len(alist)

다음 명령을 사용하여 `myfunc()`의 역 어셈블리를 표시할 수 있습니다:

    >>> dis.dis(myfunc)
      2           0 LOAD_GLOBAL              0 (len)
                  2 LOAD_FAST                0 (alist)
                  4 CALL_FUNCTION            1
                  6 RETURN_VALUE

(“2”는 줄 번호입니다).

## 바이트 코드 분석

버전 3.4에 추가.

바이트 코드 분석 API는 컴파일된 코드의 세부 사항에 쉽게 액세스 할 수 있도록 하는 `Bytecode` 객체로 파이썬 코드 조각을 감쌀 수 있도록 합니다.

class `dis.``Bytecode`(x, *, first_line=None, current_offset=None)

  함수, 제너레이터, 비동기 제너레이터, 코루틴, 메서드, 소스 코드 문자열 또는 (`compile()`에서 반환된) 코드 객체에 해당하는 바이트 코드를 분석합니다.

  이것은 아래에 나열된 많은 함수, 특히 `get_instructions()`를 둘러싼 편리한 래퍼입니다, `Bytecode` 인스턴스를 이터레이트 하면 바이트 코드 연산이 `Instruction` 인스턴스로 산출되기 때문입니다.

  first_line이 `None`이 아니면, 역 어셈블 된 코드에서 첫 번째 소스 줄에 대해 보고해야 하는 줄 번호를 나타냅니다. 그렇지 않으면, 소스 줄 정보(있다면)를 역 어셈블 된 코드 객체에서 직접 취합니다.

  current_offset이 `None`이 아니면, 역 어셈블 된 코드의 명령어 오프셋을 나타냅니다. 이를 설정하면, `dis()`가 지정된 옵코드(opcode)에 대해 “현재 명령어” 마커를 표시합니다.

  classmethod `from_traceback`(tb)

    주어진 트레이스백에서 `Bytecode` 인스턴스를 구성하고, current_offset을 예외를 일으킨 명령어로 설정합니다.

  `codeobj`

    컴파일된 코드 객체.

  `first_line`

    코드 객체의 첫 번째 소스 줄 (사용 가능하다면)

  `dis`()

    바이트 코드 연산의 포맷된 보기를 반환합니다 (`dis.dis()`가 인쇄하는 것과 같지만, 여러 줄 문자열로 반환됩니다).

  `info`()

    `code_info()`처럼, 코드 객체에 대한 자세한 정보가 포함된 포맷된 여러 줄 문자열을 반환합니다.

  버전 3.7에서 변경: 이제 코루틴과 비동기 제너레이터 객체를 처리할 수 있습니다.

예:

    >>> bytecode = dis.Bytecode(myfunc)
    >>> for instr in bytecode:
    ...     print(instr.opname)
    ...
    LOAD_GLOBAL
    LOAD_FAST
    CALL_FUNCTION
    RETURN_VALUE

## 분석 함수

`dis` 모듈은 또한 입력을 원하는 출력으로 직접 변환하는 다음 분석 함수를 정의합니다. 단일 작업만 수행해서, 중간 분석 객체가 유용하지 않을 때 유용할 수 있습니다:

`dis.``code_info`(x)

  제공된 함수, 제너레이터, 비동기 제너레이터, 코루틴, 메서드, 소스 코드 문자열 또는 코드 객체에 대한 자세한 코드 객체 정보가 포함된 포맷된 여러 줄 문자열을 반환합니다.

  코드 정보 문자열의 정확한 내용은 구현에 따라 달라지며 파이썬 VM이나 파이썬 릴리스에 걸쳐 임의로 변경될 수 있습니다.

  버전 3.2에 추가.

  버전 3.7에서 변경: 이제 코루틴과 비동기 제너레이터 객체를 처리할 수 있습니다.

`dis.``show_code`(x, *, file=None)

  제공된 함수, 메서드, 소스 코드 문자열 또는 코드 객체에 대한 자세한 코드 객체 정보를 file(또는 file이 지정되지 않으면 `sys.stdout`)로 인쇄합니다.

  이것은 `print(code_info(x), file=file)`의 편리한 축약 형으로, 인터프리터 프롬프트에서의 대화식 탐색을 위한 것입니다.

  버전 3.2에 추가.

  버전 3.4에서 변경: file 매개 변수를 추가했습니다.

`dis.``dis`(x=None, *, file=None, depth=None)

  x 객체를 역 어셈블 합니다. x는 모듈, 클래스, 메서드, 함수, 제너레이터, 비동기 제너레이터, 코루틴, 코드 객체, 소스 코드 문자열 또는 원시 바이트 코드의 바이트 시퀀스를 나타낼 수 있습니다. 모듈의 경우, 모든 함수를 역 어셈블 합니다. 클래스의 경우, 모든 메서드(클래스와 정적 메서드를 포함합니다)를 역 어셈블 합니다. 코드 객체나 원시 바이트 코드 시퀀스의 경우, 바이트 코드 명령어 당 한 줄을 인쇄합니다. 또한 중첩 코드 객체(컴프리헨션, 제너레이터 표현식 및 중첩 함수의 코드와 중첩 클래스를 만드는 데 사용된 코드)를 재귀적으로 역 어셈블 합니다. 문자열은 역 어셈블 되기 전에 먼저 `compile()` 내장 함수를 사용하여 코드 객체로 컴파일됩니다. 객체가 제공되지 않으면, 이 함수는 마지막 트레이스백을 역 어셈블 합니다.

  역 어셈블리는 제공된다면 제공된 file 인자에, 그렇지 않으면 `sys.stdout`에 텍스트로 기록됩니다.

  재귀의 최대 깊이는 `None`이 아닌 한 depth에 의해 제한됩니다. `depth=0`은 재귀가 없음을 의미합니다.

  버전 3.4에서 변경: file 매개 변수를 추가했습니다.

  버전 3.7에서 변경: 재귀 역 어셈블을 구현하고 depth 매개 변수를 추가했습니다.

  버전 3.7에서 변경: 이제 코루틴과 비동기 제너레이터 객체를 처리할 수 있습니다.

`dis.``distb`(tb=None, *, file=None)

  트레이스백의 최상단 함수를 역 어셈블 합니다. 전달되지 않으면 마지막 트레이스백을 사용합니다. 예외를 일으키는 명령어가 표시됩니다.

  역 어셈블리는 제공된다면 제공된 file 인자에, 그렇지 않으면 `sys.stdout`에 텍스트로 기록됩니다.

  버전 3.4에서 변경: file 매개 변수를 추가했습니다.

`dis.``disassemble`(code, lasti=-1, *, file=None)
`dis.``disco`(code, lasti=-1, *, file=None)

  코드 객체를 역 어셈블 하고, lasti가 제공되면 마지막 명령어를 표시합니다. 출력은 다음 열로 나뉩니다:

  1. 줄 번호, 각 줄의 첫 번째 명령어에 표시됩니다

  2. 현재 명령어, `-->`로 표시됩니다,

  3. 레이블이 있는 명령어, `>>`로 표시됩니다,

  4. 명령어의 주소,

  5. 연산 코드 이름,

  6. 연산 매개 변수, 그리고

  7. 괄호 안에 있는 매개 변수의 해석.

  매개 변수 해석은 지역과 전역 변수 이름, 상숫값, 분기 대상 및 비교 연산자를 인식합니다.

  역 어셈블리는 제공된다면 제공된 file 인자에, 그렇지 않으면 `sys.stdout`에 텍스트로 기록됩니다.

  버전 3.4에서 변경: file 매개 변수를 추가했습니다.

`dis.``get_instructions`(x, *, first_line=None)

  제공된 함수, 메서드, 소스 코드 문자열 또는 코드 객체의 명령어들에 대한 이터레이터를 반환합니다.

  이터레이터는 제공된 코드의 각 연산에 대한 세부 정보를 제공하는 `Instruction` 네임드 튜플의 연속을 생성합니다.

  first_line이 `None`이 아니면, 역 어셈블 된 코드에서 첫 번째 소스 줄에 대해 보고해야 하는 줄 번호를 나타냅니다. 그렇지 않으면, 소스 줄 정보(있다면)를 역 어셈블 된 코드 객체에서 직접 취합니다.

  버전 3.4에 추가.

`dis.``findlinestarts`(code)

  이 제너레이터 함수는 코드 객체 code의 `co_firstlineno`와 `co_lnotab` 어트리뷰트를 사용하여 소스 코드에서 줄의 시작을 가리키는 오프셋을 찾습니다. `(offset, lineno)` 쌍으로 생성됩니다. `co_lnotab` 형식과 디코딩 방법은 Objects/lnotab_notes.txt를 참조하십시오.

  버전 3.6에서 변경: 줄 번호가 줄어들 수 있습니다. 전에는, 언제나 증가했습니다.

`dis.``findlabels`(code)

  원시 컴파일된 바이트 코드 문자열 code에서 점프 대상인 모든 오프셋을 감지하고, 이러한 오프셋의 리스트를 반환합니다.

`dis.``stack_effect`(opcode, oparg=None, *, jump=None)

  인자 oparg를 갖는 opcode의 스택 효과를 계산합니다.

  코드에 점프 대상이 있고 jump가 `True`이면, `stack_effect()`는 점프의 스택 효과를 반환합니다. jump가 `False`이면, 점프하지 않는 스택 효과를 반환합니다. jump가 `None`(기본값)이면, 두 경우의 최대 스택 효과를 반환합니다.

  버전 3.4에 추가.

  버전 3.8에서 변경: jump 매개 변수를 추가했습니다.

## 파이썬 바이트 코드 명령어

`get_instructions()` 함수와 `Bytecode` 클래스는 바이트 코드 명령어의 세부 사항을 `Instruction` 인스턴스로 제공합니다:

class `dis.``Instruction`

  바이트 코드 연산에 대한 세부 사항

  `opcode`

    연산의 숫자 코드, 아래 나열된 옵코드 값과 옵코드 모음에 있는 바이트 코드 값에 해당합니다.

  `opname`

    연산의 사람이 읽을 수 있는 이름

  `arg`

    연산에 대한 숫자 인자 (있다면), 그렇지 않으면 `None`

  `argval`

    해석된(resolved) arg 값 (알고 있다면), 그렇지 않으면 arg와 같습니다

  `argrepr`

    연산 인자에 대한 사람이 읽을 수 있는 설명

  `offset`

    바이트 코드 시퀀스 내에서 연산의 시작 인덱스

  `starts_line`

    이 옵코드에 의해 시작된 줄 (있다면), 그렇지 않으면 `None`

  `is_jump_target`

    다른 코드가 여기로 점프하면 `True`, 그렇지 않으면 `False`

  버전 3.4에 추가.

파이썬 컴파일러는 현재 다음 바이트 코드 명령어를 생성합니다.

일반 명령어

`NOP`

  아무것도 하지 않는 코드. 바이트 코드 최적화기에서 자리 표시자로 사용됩니다.

`POP_TOP`

  스택 최상단 (TOS) 항목을 제거합니다.

`ROT_TWO`

  두 개의 최상위 스택 항목을 자리바꿈합니다.

`ROT_THREE`

  두 번째와 세 번째 스택 항목을 한 자리 위로 들어 올리고, 최상단 항목을 세 번째 자리로 내립니다.

`ROT_FOUR`

  Lifts second, third and fourth stack items one position up, moves top down to position four.

  버전 3.8에 추가.

`DUP_TOP`

  스택 최상단의 참조를 복제합니다.

  버전 3.2에 추가.

`DUP_TOP_TWO`

  같은 순서를 유지하면서, 스택 최상단의 두 참조를 복제합니다.

  버전 3.2에 추가.

단항 연산

단항 연산은 스택의 최상단을 취하고, 연산을 적용한 다음, 결과를 스택에 다시 푸시합니다.

`UNARY_POSITIVE`

  `TOS = +TOS`를 구현합니다.

`UNARY_NEGATIVE`

  `TOS = -TOS`를 구현합니다.

`UNARY_NOT`

  `TOS = not TOS`를 구현합니다.

`UNARY_INVERT`

  `TOS = ~TOS`를 구현합니다.

`GET_ITER`

  `TOS = iter(TOS)`를 구현합니다.

`GET_YIELD_FROM_ITER`

  `TOS`가 제너레이터 이터레이터나 코루틴 객체이면 그대로 둡니다. 그렇지 않으면, `TOS = iter(TOS)`를 구현합니다.

  버전 3.5에 추가.

이항 연산

이항 연산은 스택에서 스택 최상단(TOS)과 두 번째 최상단 스택 항목(TOS1)을 제거합니다. 연산을 수행하고, 결과를 다시 스택에 넣습니다.

`BINARY_POWER`

  `TOS = TOS1 ** TOS`를 구현합니다.

`BINARY_MULTIPLY`

  `TOS = TOS1 * TOS`를 구현합니다.

`BINARY_MATRIX_MULTIPLY`

  `TOS = TOS1 @ TOS`를 구현합니다.

  버전 3.5에 추가.

`BINARY_FLOOR_DIVIDE`

  `TOS = TOS1 // TOS`를 구현합니다.

`BINARY_TRUE_DIVIDE`

  `TOS = TOS1 / TOS`를 구현합니다.

`BINARY_MODULO`

  `TOS = TOS1 % TOS`를 구현합니다.

`BINARY_ADD`

  `TOS = TOS1 + TOS`를 구현합니다.

`BINARY_SUBTRACT`

  `TOS = TOS1 - TOS`를 구현합니다.

`BINARY_SUBSCR`

  `TOS = TOS1[TOS]`를 구현합니다.

`BINARY_LSHIFT`

  `TOS = TOS1 << TOS`를 구현합니다.

`BINARY_RSHIFT`

  `TOS = TOS1 >> TOS`를 구현합니다.

`BINARY_AND`

  `TOS = TOS1 & TOS`를 구현합니다.

`BINARY_XOR`

  `TOS = TOS1 ^ TOS`를 구현합니다.

`BINARY_OR`

  `TOS = TOS1 | TOS`를 구현합니다.

제자리 연산

제자리(in-place) 연산은 TOS와 TOS1을 제거하고, 스택에 결과를 다시 푸시한다는 점에서 이항 연산과 같습니다. 그러나 TOS1이 이를 지원하면 연산이 제자리에서 수행되며, 결과 TOS는 원래 TOS1일 수 있습니다 (하지만 꼭 그럴 필요는 없습니다).

`INPLACE_POWER`

  제자리 `TOS = TOS1 ** TOS`를 구현합니다.

`INPLACE_MULTIPLY`

  제자리 `TOS = TOS1 * TOS`를 구현합니다.

`INPLACE_MATRIX_MULTIPLY`

  제자리 `TOS = TOS1 @ TOS`를 구현합니다.

  버전 3.5에 추가.

`INPLACE_FLOOR_DIVIDE`

  제자리 `TOS = TOS1 // TOS`를 구현합니다.

`INPLACE_TRUE_DIVIDE`

  제자리 `TOS = TOS1 / TOS`를 구현합니다.

`INPLACE_MODULO`

  제자리 `TOS = TOS1 % TOS`를 구현합니다.

`INPLACE_ADD`

  제자리 `TOS = TOS1 + TOS`를 구현합니다.

`INPLACE_SUBTRACT`

  제자리 `TOS = TOS1 - TOS`를 구현합니다.

`INPLACE_LSHIFT`

  제자리 `TOS = TOS1 << TOS`를 구현합니다.

`INPLACE_RSHIFT`

  제자리 `TOS = TOS1 >> TOS`를 구현합니다.

`INPLACE_AND`

  제자리 `TOS = TOS1 & TOS`를 구현합니다.

`INPLACE_XOR`

  제자리 `TOS = TOS1 ^ TOS`를 구현합니다.

`INPLACE_OR`

  제자리 `TOS = TOS1 | TOS`를 구현합니다.

`STORE_SUBSCR`

  `TOS1[TOS] = TOS2`를 구현합니다.

`DELETE_SUBSCR`

  `del TOS1[TOS]`를 구현합니다.

코루틴 옵코드

`GET_AWAITABLE`

  `TOS = get_awaitable(TOS)`를 구현합니다. 여기서 `o`가 코루틴 객체나 CO_ITERABLE_COROUTINE 플래그를 가진 제너레이터 객체이면 `get_awaitable(o)`는 `o`를 반환합니다, 또는 `o.__await__`를 해석(resolve)합니다.

  버전 3.5에 추가.

`GET_AITER`

  `TOS = TOS.__aiter__()`를 구현합니다.

  버전 3.5에 추가.

  버전 3.7에서 변경: `__aiter__`로부터 어웨이터블 객체를 반환하는 것은 더는 지원되지 않습니다.

`GET_ANEXT`

  `PUSH(get_awaitable(TOS.__anext__()))`를 구현합니다. `get_awaitable`에 대한 자세한 내용은 `GET_AWAITABLE`을 참조하십시오.

  버전 3.5에 추가.

`END_ASYNC_FOR`

  `async for` 루프를 종료합니다. 다음 항목을 어웨이트 할 때 발생하는 예외를 처리합니다. TOS가 `StopAsyncIteration` 이면 스택에서 7개의 값을 팝하고 두 번째 세 개를 사용하여 예외 상태를 복원합니다. 그렇지 않으면 스택에서 세 값을 사용하여 예외를 다시 발생시킵니다. 예외 처리기 블록이 블록 스택에서 제거됩니다.

  버전 3.8에 추가.

`BEFORE_ASYNC_WITH`

  스택 최상단의 객체에서 `__aenter__`와 `__aexit__`를 해석(resolve)합니다. `__aexit__`와 `__aenter__()`의 결과를 스택으로 푸시합니다.

  버전 3.5에 추가.

`SETUP_ASYNC_WITH`

  새 프레임 객체를 만듭니다.

  버전 3.5에 추가.

기타 옵코드

`PRINT_EXPR`

  대화식 모드를 위한 표현식 문을 구현합니다. 스택에서 TOS가 제거되고 인쇄됩니다. 비 대화식 모드에서, 표현식 문은 `POP_TOP`으로 종료됩니다.

`SET_ADD`(i)

  `set.add(TOS1[-i], TOS)`를 호출합니다. 집합 컴프리헨션을 구현하는 데 사용됩니다.

`LIST_APPEND`(i)

  `list.append(TOS1[-i], TOS)`를 호출합니다. 리스트 컴프리헨션을 구현하는 데 사용됩니다.

`MAP_ADD`(i)

  `dict.__setitem__(TOS1[-i], TOS1, TOS)`를 호출합니다. 딕셔너리 컴프리헨션을 구현하는 데 사용됩니다.

  버전 3.1에 추가.

  버전 3.8에서 변경: 맵 값은 TOS이고 맵 키는 TOS1입니다. 전에는, 이것들이 반대였습니다.

모든 `SET_ADD`, `LIST_APPEND` 및 `MAP_ADD` 명령어에 대해, 추가된 값이나 키/값 쌍이 팝 되지만, 컨테이너 객체는 스택에 남아 있어서 루프의 추가 이터레이션에 사용할 수 있습니다.

`RETURN_VALUE`

  TOS를 함수 호출자에게 반환합니다.

`YIELD_VALUE`

  TOS를 팝하고 제너레이터에서 그것을 산출합니다.

`YIELD_FROM`

  TOS를 팝하고 제너레이터에서 서브 이터레이터로 그것에 위임합니다.

  버전 3.3에 추가.

`SETUP_ANNOTATIONS`

  `locals()`에 `__annotations__`가 정의되어 있는지 확인합니다, 그렇지 않으면 비어있는 `dict`로 설정됩니다. 이 옵코드는 클래스나 모듈 본문에 변수 어노테이션이 정적으로 포함될 때만 생성됩니다.

  버전 3.6에 추가.

`IMPORT_STAR`

  `'_'`로 시작하지 않는 모든 심볼을 모듈 TOS에서 지역 이름 공간으로 직접 로드합니다. 모든 이름을 로드한 후 모듈이 팝 됩니다. 이 옵코드는 `from module import *`를 구현합니다.

`POP_BLOCK`

  블록 스택에서 하나의 블록을 제거합니다. 프레임마다, 블록 스택이 있습니다, `try` 문을 나타내는 것과 같은 것들입니다.

`POP_EXCEPT`

  블록 스택에서 하나의 블록을 제거합니다. 팝 된 블록은 예외 처리기에 진입할 때 묵시적으로 만들어진 예외 처리기 블록이어야 합니다. 프레임 스택에서 추가적인 값들을 팝 하는 것에 더해, 마지막 3개의 팝 된 값이 예외 상태를 복원하는 데 사용됩니다.

`POP_FINALLY`(preserve_tos)

  값 스택과 블록 스택을 정리합니다. preserve_tos가 `0`이 아니면 TOS가 먼저 스택에서 팝 되고 다른 스택 연산을 수행한 후 스택으로 푸시 됩니다:

  - TOS가 `NULL`이거나 정수(`BEGIN_FINALLY`나 `CALL_FINALLY`로 푸시 된)이면 스택에서 팝 됩니다.

  - TOS가 예외 형(예외가 발생했을 때 푸시 된)이면 스택에서 6개의 값이 팝 됩니다, 마지막 3개의 팝 된 값이 예외 상태를 복원하는 데 사용됩니다. 예외 처리기 블록이 블록 스택에서 제거됩니다.

  `END_FINALLY`와 비슷하지만, 바이트 코드 카운터를 변경하거나 예외를 발생시키지 않습니다. `finally` 블록에 있는 `break`, `continue` 및 `return`을 구현하는 데 사용됩니다.

  버전 3.8에 추가.

`BEGIN_FINALLY`

  `END_FINALLY`, `POP_FINALLY`, `WITH_CLEANUP_START` 및 `WITH_CLEANUP_FINISH`에서 사용하기 위해 `NULL`을 스택으로 푸시합니다. `finally` 블록을 시작합니다.

  버전 3.8에 추가.

`END_FINALLY`

  `finally` 절을 종료합니다. 인터프리터는 TOS의 값에 따라 예외를 다시 발생시켜야 하는지 또는 실행을 계속해야 하는지 기억합니다.

  - TOS가 `NULL`(`BEGIN_FINALLY`에 의해 푸시 된)이면 다음 명령어부터 계속합니다. TOS가 팝 됩니다.

  - TOS가 정수(`CALL_FINALLY`에 의해 푸시 된)이면, 바이트 코드 카운터를 TOS로 설정합니다. TOS가 팝 됩니다.

  - TOS가 예외 형(예외가 발생했을 때 푸시 된)이면 스택에서 6개의 값이 팝 되고, 처음 3개의 팝 된 값이 예외를 다시 발생시키는 데 사용되고 마지막 3개의 팝 된 값이 예외 상태를 복원하는 데 사용됩니다. 예외 처리기 블록이 블록 스택에서 제거됩니다.

`LOAD_BUILD_CLASS`

  `builtins.__build_class__()`를 스택으로 푸시합니다. 나중에 클래스를 생성하기 위해 `CALL_FUNCTION`에 의해 호출됩니다.

`SETUP_WITH`(delta)

  이 옵코드는 with 블록이 시작되기 전에 여러 연산을 수행합니다. 먼저 컨텍스트 관리자에서 `__exit__()`를 로드하고 나중에 `WITH_CLEANUP_START`에서 사용할 수 있도록 스택으로 푸시합니다. 그런 다음, `__enter__()`가 호출되고, delta를 가리키는 finally 블록이 푸시 됩니다. 마지막으로, `__enter__()` 메서드 호출 결과가 스택으로 푸시 됩니다. 다음 옵코드는 이를 무시하거나 (`POP_TOP`), 변수에 저장합니다 (`STORE_FAST`, `STORE_NAME` 또는 `UNPACK_SEQUENCE`).

  버전 3.2에 추가.

`WITH_CLEANUP_START`

  `with` 문 블록이 종료될 때 스택 정리를 시작합니다.

  스택의 맨 위에는 `NULL`(`BEGIN_FINALLY`가 푸시한)이나 with 블록에서 예외가 발생했으면 6개의 값이 푸시 됩니다. 아래는 컨텍스트 관리자의 `__exit__()`나 `__aexit__()` 연결된 메서드입니다.

  TOS가 `NULL`이면, `SECOND(None, None, None)`을 호출하고, 스택에서 함수를 제거하고, TOS를 남겨두고, `None`을 스택으로 푸시합니다. 그렇지 않으면 `SEVENTH(TOP, SECOND, THIRD)`를 호출하고, 스택의 맨 아래 3개 값을 아래로 시프트하고, 빈 지점을 `NULL`로 바꾸고, TOS를 푸시합니다. 마지막으로 호출 결과를 푸시합니다.

`WITH_CLEANUP_FINISH`

  `with` 문 블록이 종료될 때 스택 정리를 완료합니다.

  TOS는 `WITH_CLEANUP_START`에 의해 푸시 된 `__exit__()`나 `__aexit__()` 함수 호출의 결과입니다. SECOND는 `None`이나 예외 형(예외가 발생할 때 푸시 된)입니다.

  스택에서 두 값을 팝 합니다. SECOND가 None이 아니고 TOS가 참이면 예외가 잡혔을 때 만들어진 EXCEPT_HANDLER 블록을 되감고 `NULL`을 스택으로 푸시합니다.

다음 옵코드는 모두 인자를 사용합니다.

`STORE_NAME`(namei)

  `name = TOS`를 구현합니다. namei는 코드 객체의 `co_names` 어트리뷰트에서 name의 인덱스입니다. 컴파일러는 가능하면 `STORE_FAST`나 `STORE_GLOBAL`을 사용하려고 합니다.

`DELETE_NAME`(namei)

  `del name`을 구현합니다. 여기서 namei는 코드 객체의 `co_names` 어트리뷰트에서의 인덱스입니다.

`UNPACK_SEQUENCE`(count)

  TOS를 count 개 개별 값으로 언팩합니다. 이 값들은 오른쪽에서 왼쪽으로 스택에 넣습니다.

`UNPACK_EX`(counts)

  스타드 타깃(starred target)으로의 대입을 구현합니다: TOS의 이터러블을 개별 값으로 언팩합니다. 여기서 값의 총수는 이터러블의 항목 수보다 적을 수 있습니다: 새 값 중 하나는 남은 모든 항목의 리스트입니다.

  counts의 하위 바이트는 리스트값 이전의 값의 개수이고, counts의 상위 바이트는 그 이후의 값의 개수입니다. 결괏값들은 오른쪽에서 왼쪽으로 스택에 넣습니다.

`STORE_ATTR`(namei)

  `TOS.name = TOS1`을 구현합니다. 여기서 namei는 `co_names`에서 name의 인덱스입니다.

`DELETE_ATTR`(namei)

  namei를 `co_names`에서의 인덱스로 사용하여, `del TOS.name`을 구현합니다.

`STORE_GLOBAL`(namei)

  `STORE_NAME`처럼 작동하지만, 이름을 전역으로 저장합니다.

`DELETE_GLOBAL`(namei)

  `DELETE_NAME`처럼 작동하지만, 전역 이름을 삭제합니다.

`LOAD_CONST`(consti)

  `co_consts[consti]`를 스택으로 푸시합니다.

`LOAD_NAME`(namei)

  `co_names[namei]`와 연관된 값을 스택으로 푸시합니다.

`BUILD_TUPLE`(count)

  스택에서 count 개의 항목을 소비하는 튜플을 만들고, 결과 튜플을 스택으로 푸시합니다.

`BUILD_LIST`(count)

  `BUILD_TUPLE`처럼 작동하지만, 리스트를 만듭니다.

`BUILD_SET`(count)

  `BUILD_TUPLE`처럼 작동하지만, 집합을 만듭니다.

`BUILD_MAP`(count)

  새 딕셔너리 객체를 스택으로 푸시합니다. 딕셔너리가 count 항목을 갖도록 `2 * count` 항목을 팝 합니다: `{..., TOS3: TOS2, TOS1: TOS}`.

  버전 3.5에서 변경: 딕셔너리는 count 항목을 갖도록 미리 크기가 조정된 빈 딕셔너리를 만드는 대신 스택 항목에서 만들어집니다.

`BUILD_CONST_KEY_MAP`(count)

  상수 키에 특화된 `BUILD_MAP` 버전. 키의 튜플이 포함된 스택의 맨 위 요소를 팝 한 다음, `TOS1`에서 시작하여, count 개의 값을 팝 하여 만들어지는 딕셔너리의 값을 형성합니다.

  버전 3.6에 추가.

`BUILD_STRING`(count)

  스택에서 count 문자열을 이어붙이고 결과 문자열을 스택으로 푸시합니다.

  버전 3.6에 추가.

`BUILD_TUPLE_UNPACK`(count)

  스택에서 count 이터러블을 팝하고, 단일 튜플로 연결하여, 결과를 푸시합니다. 튜플 디스플레이에서의 이터러블 언 패킹을 구현합니다 `(*x, *y, *z)`.

  버전 3.5에 추가.

`BUILD_TUPLE_UNPACK_WITH_CALL`(count)

  이것은 `BUILD_TUPLE_UNPACK`과 유사하지만, `f(*x, *y, *z)` 호출 문법에 사용됩니다. `count + 1` 위치의 스택 항목은 해당 콜러블 `f`여야 합니다.

  버전 3.6에 추가.

`BUILD_LIST_UNPACK`(count)

  이것은 `BUILD_TUPLE_UNPACK`과 비슷하지만, 튜플 대신 리스트를 푸시합니다. 리스트 디스플레이에서의 이터러블 언 패킹을 구현합니다 `[*x, *y, *z]`.

  버전 3.5에 추가.

`BUILD_SET_UNPACK`(count)

  이것은 `BUILD_TUPLE_UNPACK`과 비슷하지만, 튜플 대신 집합을 푸시합니다. 집합 디스플레이에서의 이터러블 언 패킹을 구현합니다 `{*x, *y, *z}`.

  버전 3.5에 추가.

`BUILD_MAP_UNPACK`(count)

  스택에서 count 매핑을 팝 하여, 단일 딕셔너리에 병합하고, 결과를 푸시합니다. 딕셔너리 디스플레이에서의 딕셔너리 언 패킹을 구현합니다 `{**x, **y, **z}`.

  버전 3.5에 추가.

`BUILD_MAP_UNPACK_WITH_CALL`(count)

  이것은 `BUILD_MAP_UNPACK`과 유사하지만, `f(**x, **y, **z)` 호출 문법에 사용됩니다. `count + 2` 위치의 스택 항목은 해당 콜러블 `f`여야 합니다.

  버전 3.5에 추가.

  버전 3.6에서 변경: 콜러블의 위치는 인자의 두 번째 바이트에 인코딩하는 대신 옵코드 인자에 2를 더해서 결정됩니다.

`LOAD_ATTR`(namei)

  TOS를 `getattr(TOS, co_names[namei])`로 바꿉니다.

`COMPARE_OP`(opname)

  불리언 연산을 수행합니다. 연산 이름은 `cmp_op[opname]`에서 찾을 수 있습니다.

`IMPORT_NAME`(namei)

  모듈 `co_names[namei]`를 임포트 합니다. TOS와 TOS1이 팝 되고 `__import__()`의 fromlist와 level 인자를 제공합니다. 모듈 객체가 스택으로 푸시 됩니다. 현재 이름 공간은 영향을 받지 않습니다: 올바른 import 문을 위해, 후속 `STORE_FAST` 명령어가 이름 공간을 수정합니다.

`IMPORT_FROM`(namei)

  TOS에서 발견된 모듈에서 어트리뷰트 `co_names[namei]`를 로드합니다. 결과 객체는 스택에 푸시 되어, 뒤따르는 `STORE_FAST` 명령어로 저장됩니다.

`JUMP_FORWARD`(delta)

  바이트 코드 카운터를 delta만큼 증가시킵니다.

`POP_JUMP_IF_TRUE`(target)

  TOS가 참이면, 바이트 코드 카운터를 target으로 설정합니다. TOS가 팝 됩니다.

  버전 3.1에 추가.

`POP_JUMP_IF_FALSE`(target)

  TOS가 거짓이면, 바이트 코드 카운터를 target으로 설정합니다. TOS가 팝 됩니다.

  버전 3.1에 추가.

`JUMP_IF_TRUE_OR_POP`(target)

  TOS가 참이면, 바이트 코드 카운터를 target으로 설정하고 스택에 TOS를 남겨 둡니다. 그렇지 않으면 (TOS가 거짓이면), TOS가 팝 됩니다.

  버전 3.1에 추가.

`JUMP_IF_FALSE_OR_POP`(target)

  TOS가 거짓이면, 바이트 코드 카운터를 target으로 설정하고 스택에 TOS를 남겨 둡니다. 그렇지 않으면 (TOS가 참이면), TOS가 팝 됩니다.

  버전 3.1에 추가.

`JUMP_ABSOLUTE`(target)

  바이트 코드 카운터를 target으로 설정합니다.

`FOR_ITER`(delta)

  TOS는 이터레이터입니다. 그것의 `__next__()` 메서드를 호출합니다. 이것이 새로운 값을 산출하면, 스택에 푸시합니다 (그 밑에 이터레이터를 남겨둡니다). 이터레이터가 소진되었음을 표시하면 TOS가 팝 되고, 바이트 코드 카운터가 delta만큼 증가합니다.

`LOAD_GLOBAL`(namei)

  `co_names[namei]`라는 이름의 전역을 스택에 로드합니다.

`SETUP_FINALLY`(delta)

  try-finally나 try-except 절의 try 블록을 블록 스택으로 푸시합니다. delta는 finally 블록이나 첫 번째 except 블록을 가리킵니다.

`CALL_FINALLY`(delta)

  다음 명령어의 주소를 스택으로 푸시하고 바이트 코드 카운터를 delta만큼 증가시킵니다. finally 블록을 “서브 루틴”으로 호출하는 데 사용됩니다.

  버전 3.8에 추가.

`LOAD_FAST`(var_num)

  지역 `co_varnames[var_num]`에 대한 참조를 스택으로 푸시합니다.

`STORE_FAST`(var_num)

  TOS를 지역 `co_varnames[var_num]`에 저장합니다.

`DELETE_FAST`(var_num)

  지역 `co_varnames[var_num]`을 삭제합니다.

`LOAD_CLOSURE`(i)

  셀과 자유 변수 스토리지의 슬롯 i에 포함된 셀에 대한 참조를 푸시합니다. i가 co_cellvars의 길이보다 작으면 변수 이름은 `co_cellvars[i]`입니다. 그렇지 않으면 `co_freevars[i - len(co_cellvars)]`입니다.

`LOAD_DEREF`(i)

  셀과 자유 변수 스토리지의 슬롯 i에 포함된 셀을 로드합니다. 스택에 포함된 셀 객체에 대한 참조를 푸시합니다.

`LOAD_CLASSDEREF`(i)

  `LOAD_DEREF`와 비슷하지만, 셀을 참조하기 전에 먼저 지역 딕셔너리를 확인합니다. 이것은 클래스 본문에서 자유 변수를 로드하는 데 사용됩니다.

  버전 3.4에 추가.

`STORE_DEREF`(i)

  TOS를 셀과 자유 변수 스토리지의 슬롯 i에 포함된 셀에 저장합니다.

`DELETE_DEREF`(i)

  셀과 자유 변수 스토리지의 슬롯 i에 포함된 셀을 비웁니다. `del` 문에서 사용됩니다.

  버전 3.2에 추가.

`RAISE_VARARGS`(argc)

  argc의 값에 따라, `raise` 문의 3가지 형식 중 하나를 사용하여 예외를 발생시킵니다:

  - 0: `raise` (이전 예외를 다시 발생시킵니다)

  - 1: `raise TOS` (`TOS`에 있는 예외 인스턴스나 형을 발생시킵니다)

  - 2: `raise TOS1 from TOS` (`__cause__`가 `TOS`로 설정된 `TOS1`에 있는 예외 인스턴스나 형을 발생시킵니다)

`CALL_FUNCTION`(argc)

  위치 인자를 사용하여 콜러블 객체를 호출합니다. argc는 위치 인자의 수를 나타냅니다. 스택의 맨 위에는 위치 인자가 포함되는데, 가장 오른쪽 인자가 맨 위에 있습니다. 인자 아래에는 호출할 콜러블 객체가 있습니다. `CALL_FUNCTION`은 모든 인자와 콜러블 객체를 스택에서 팝하고, 해당 인자로 콜러블 객체를 호출한 다음 콜러블 객체가 반환한 반환 값을 푸시 합니다.

  버전 3.6에서 변경: 이 옵코드는 위치 인자가 있는 호출에만 사용됩니다.

`CALL_FUNCTION_KW`(argc)

  위치(있다면)와 키워드 인자를 사용하여 콜러블 객체를 호출합니다. argc는 위치와 키워드 인자의 총수를 나타냅니다. 스택의 최상위 요소에는 키워드 인자 이름의 튜플이 포함되어 있습니다. 그 아래에는 튜플에 해당하는 순서로 키워드 인자가 옵니다. 그 아래는 위치 인자인데, 가장 오른쪽 매개 변수가 맨 위에 옵니다. 인자 아래에는 호출할 콜러블 객체가 있습니다. `CALL_FUNCTION_KW`는 모든 인자와 콜러블 객체를 스택에서 팝하고, 해당 인자로 콜러블 객체를 호출한 다음, 콜러블 객체가 반환한 반환 값을 푸시합니다.

  버전 3.6에서 변경: 키워드 인자는 딕셔너리 대신 튜플에 담기며, argc는 전체 인자 수를 나타냅니다.

`CALL_FUNCTION_EX`(flags)

  위치와 키워드 인자의 변수 집합으로 콜러블 객체를 호출합니다. flags의 최하위 비트가 설정되면, 스택의 맨 위에 추가 키워드 인자가 포함된 매핑 객체가 포함됩니다. 그 아래에는 위치 인자와 호출할 콜러블 객체가 포함된 이터러블 객체가 있습니다. `BUILD_MAP_UNPACK_WITH_CALL`과 `BUILD_TUPLE_UNPACK_WITH_CALL`은 인자를 포함하는 여러 매핑 객체와 이터러블을 병합하는 데 사용할 수 있습니다. 콜러블이 호출되기 전에, 매핑 객체와 이터러블 객체는 각각 “언팩” 되고 그 내용이 각각 키워드와 위치 인자로 전달됩니다. `CALL_FUNCTION_EX`는 모든 인자와 콜러블 객체를 스택에서 팝하고, 해당 인자로 콜러블 객체를 호출한 다음, 콜러블 객체가 반환한 반환 값을 푸시합니다.

  버전 3.6에 추가.

`LOAD_METHOD`(namei)

  TOS 객체에서 `co_names[namei]`라는 이름의 메서드를 로드합니다. TOS가 팝 됩니다. 이 바이트 코드는 두 가지 경우를 구별합니다: TOS에 올바른 이름의 메서드가 있으면, 바이트 코드는 연결되지 않은 메서드와 TOS를 푸시합니다. TOS는 연결되지 않은 메서드를 호출할 때 `CALL_METHOD`에서 첫 번째 인자(`self`)로 사용됩니다. 그렇지 않으면, `NULL`과 어트리뷰트 조회에 의해 반환된 객체가 푸시 됩니다.

  버전 3.7에 추가.

`CALL_METHOD`(argc)

  메서드를 호출합니다. argc는 위치 인자의 수입니다. 키워드 인자는 지원되지 않습니다. 이 옵코드는 `LOAD_METHOD`와 함께 사용하도록 설계되었습니다. 위치 인자는 스택 맨 위에 있습니다. 그 아래에, `LOAD_METHOD`에 설명된 두 항목이 스택에 있습니다 (`self`와 연결되지 않은 메서드 객체 또는 `NULL`과 임의의 콜러블). 이것들이 모두 팝 되고 반환 값이 푸시 됩니다.

  버전 3.7에 추가.

`MAKE_FUNCTION`(flags)

  스택에 새 함수 객체를 푸시합니다. 바닥에서 맨 위로, 인자가 지정된 플래그 값을 전달하면 소비되는 스택은 값으로 구성되어야 합니다.

  - `0x01` 위치 전용과 위치-키워드 매개 변수를 위한 기본값의 위치 순서 튜플

  - `0x02` 키워드 전용 매개 변수의 기본값 딕셔너리

  - `0x04` 어노테이션 딕셔너리

  - `0x08` 자유 변수를 위한 셀을 포함하는 튜플, 클로저를 만듭니다

  - 함수와 연관된 코드 (TOS1에)

  - 함수의 정규화된 이름 (TOS에)

`BUILD_SLICE`(argc)

  스택에 슬라이스 객체를 푸시합니다. argc는 2나 3이어야 합니다. 2이면, `slice(TOS1, TOS)`가 푸시 됩니다; 3이면, `slice(TOS2, TOS1, TOS)`가 푸시 됩니다. 자세한 정보는 `slice()` 내장 함수를 참조하십시오.

`EXTENDED_ARG`(ext)

  너무 커서 기본 1바이트에 맞지 않는 인자를 가진 옵코드에 접두어로 붙입니다. ext는 인자에서 더 높은 비트로 작동하는 추가 바이트를 보유합니다. 각 옵코드마다, 최대 3개의 접두사 `EXTENDED_ARG`가 허용되며, 2바이트에서 4바이트 사이의 인자를 형성합니다.

`FORMAT_VALUE`(flags)

  포맷 문자열 리터럴(f-문자열)을 구현하는 데 사용됩니다. 스택에서 선택적 fmt_spec을 팝 한 다음, 필수 value를 팝 합니다. flags는 다음과 같이 해석됩니다:

  - `(flags & 0x03) == 0x00`: value는 있는 그대로 포맷됩니다.

  - `(flags & 0x03) == 0x01`: 포맷하기 전에 value에 대해 `str()`을 호출합니다.

  - `(flags & 0x03) == 0x02`: 포맷하기 전에 value에 대해 `repr()`을 호출합니다.

  - `(flags & 0x03) == 0x03`: 포맷하기 전에 value에 대해 `ascii()`를 호출합니다.

  - `(flags & 0x04) == 0x04`: 스택에서 fmt_spec을 팝 하고 그것을 사용합니다, 그렇지 않으면 빈 fmt_spec을 사용합니다.

  `PyObject_Format()`을 사용하여 포맷이 수행됩니다. 결과는 스택에 푸시 됩니다.

  버전 3.6에 추가.

`HAVE_ARGUMENT`

  이것은 진짜 옵코드가 아닙니다. 인자를 사용하지 않는 옵코드와 사용하는 옵코드 사이의 구분 선을 식별합니다 (각각, `< HAVE_ARGUMENT`와 `>= HAVE_ARGUMENT`).

  버전 3.6에서 변경: 이제 모든 명령어에는 인자가 있지만, `< HAVE_ARGUMENT`인 옵코드는 이를 무시합니다. 이전에는, `>= HAVE_ARGUMENT`인 옵코드에만 인자가 있었습니다.

## 옵코드 모음

이 모음은 바이트 코드 명령어의 자동 검사를 위해 제공됩니다:

`dis.``opname`

  연산 이름의 시퀀스, 바이트 코드를 사용하여 인덱싱할 수 있습니다.

`dis.``opmap`

  연산 이름을 바이트 코드로 매핑하는 딕셔너리.

`dis.``cmp_op`

  모든 비교 연산 이름의 시퀀스.

`dis.``hasconst`

  상수에 액세스하는 바이트 코드의 시퀀스.

`dis.``hasfree`

  자유 변수에 액세스하는 바이트 코드의 시퀀스 (이 문맥에서 ‘자유’는 내부 스코프에서 참조되는 현재 스코프의 이름이나 이 스코프에서 참조되는 외부 스코프의 이름을 나타냅니다. 전역이나 내장 스코프에 대한 참조는 포함하지 않습니다).

`dis.``hasname`

  어트리뷰트를 이름으로 액세스하는 바이트 코드의 시퀀스.

`dis.``hasjrel`

  상대 점프 대상이 있는 바이트 코드의 시퀀스.

`dis.``hasjabs`

  절대 점프 대상이 있는 바이트 코드의 시퀀스.

`dis.``haslocal`

  지역 변수에 액세스하는 바이트 코드의 시퀀스.

`dis.``hascompare`

  불리언 연산의 바이트 코드의 시퀀스.