About Python Code Object
참고
https://stackoverflow.com/questions/33683217/python-code-type-flags https://www.slideshare.net/daykim7/pyconkr-2018-deep-dive-into-coroutine-110194978/1
Python 기준 버전 3.7.0
Python Code Object
파이썬의 function 및 모든 코드에는 __code__ 라는 속성이 있다
이 속성은 해당 function 및 모든 코드를 분석하는데 도움이 되는 속성이다
이번 포스팅에서는 해당 __code__ 의 중요한 속성 몇개를 써보려 한다
__code__ object
example code
def add_c(a, b): print(a, b) c = int(5) return a + b + c
__code__.co_consts
해당 코드에서 사용한 상수 값을 모두 모아놓은 속성이다
print(add_c.__code__.co_consts)
>> (None, 5)
첫번째 인자가 None 인 이유는 docstring을 작성하지 않았기 때문이다
docstring 을 작성하게 되면 첫번째 인자에 들어가게 된다
또한, function 내부에 function 을 작성하는 경우 co_consts 변수에 추가되게 된다
__code__.co_flags
print(add_c.__code__.co_flags)
>> 67
co_flags 는 해당 코드에 속성으로써, 다음을 통해 확인이 가능하다
import dis
print(dis.COMPILER_FLAG_NAMES)
>> {
1: 'OPTIMIZED', # 최적화 여부
2: 'NEWLOCALS',
4: 'VARARGS', # *arguments 구문 사용
8: 'VARKEYWORDS', # **keywords 구문 사용
16: 'NESTED',
32: 'GENERATOR', # 제네레이터
64: 'NOFREE', # *args, **kwargs 비사용
128: 'COROUTINE', # 동기 코루틴
256: 'ITERABLE_COROUTINE',
512: 'ASYNC_GENERATOR' # 비동기 제네레이터
}
와 같이 이해하고 있으며, 단순 해당 코드의 속성이라고 보면 될듯 하다
계산법은 67 과 같이 나오면 and 연산을 통하여 계산하면 된다.
67 = 0100 0011
OPTIMIZED = 0000 0001
NEWLOCALS = 0000 0010
NOFREE = 0100 0000
따라서 해당 값은 OPTIMIZED, NEWLOCALS, NOFREE 이 적용되어 있다
__code__.co_varnames
print(add_c.__code__.co_varnames)
>> ('a', 'b', 'c')
코드에서 사용한 변수 이름이 담겨있다
__code__.co_names
print(add_c.__code__.co_names)
>> ('print', 'int')
내부적으로 사용한 함수의 이름이 담겨있다
__code__.co_code
for byte in bytes(add_c.__code__.co_code):
print(f'{byte:x} ', end='')
>> 116 0 124 0 124 1 131 2 1 0 116 1 100 1 131 1 125 2 124 0 124 1 23 0 124 2 23 0 83 0
파이썬의 byte 코드가 담겨있으며, 내용은 dis.dis(add_c) 와 같다 순서대로 한글자씩 해석하면 되며,
opcode 는 dis.opmap[116] 과 같이 확인이 가능하다
116 0 # LOAD_GLOBAL 0
124 0 # LOAD_FAST 0
124 1 # LOAD_FAST 1
131 2 # CALL_FUNCTION 2
...
바이트 코드에 관련된 간단한 내용은 다음 링크 를 참조하면 된다