python에서 원시 바이트 코드를 만드는 방법
15864 단어 programmingpythontutorialbytecode
소개하다.
우선, 나는 github.io에서 이 일을 시작했지만, 나중에 한 무리의 사이버 도적들이 나를 때려서 이 신기한 사이트를 가지는 것은 무의미하다는 것을 깨달았다.그래, 그렇다. 나는 이것을 사용한다. 제목에서 말한 바와 같이 이것은 원시적인python 바이트 코드 강좌이다. 나는 네가 그것을 좋아하길 바란다. (두 번째 부분이 있기 때문이다.)
선결 조건
파이썬이란?
파이톤은 다중 반경 해석의 프로그래밍 언어로 다중성, 대상방향 프로그래밍(OOP/OOP)과 명령식 프로그래밍을 지원한다.
그것은 어떻게 일합니까?
파이썬은 이름이 붙은 것처럼 해석적인 언어이다. 이것은 컴퓨터가 할 일과 당신이 쓴 것을 해석기를 통해 연결한다는 것을 의미한다.파이톤은 C나 C++ 프로그램처럼 기계 코드를 만들지 않고 자바처럼 많이 혹은 적게 작동하며 바이트 코드를 설명하는 가상 컴퓨터를 가지고 있다.이 기본 해석기는 CPython입니다. 컴퓨터에서 바이트 코드를 실행하는 것을 책임집니다.여기서 우리는 컴파일러를 사용하지 않고 언어를 처리해야 한다. 기본적으로 서면 코드를 바이트 코드로 번역한 후에 이를 해석하는 해석기이다.그 중에는 IronPython(C# 구현), Jython(순수 자바 구현), Micropython(마이크로 컨트롤러에서 실행되는 C 버전으로 최적화) 등 여러 가지가 있다.
다음은 Python의 작업 원리도와 작성한 코드를 해석기가 실행하는 절차입니다.
사용 가능한 바이트 코드를 만드는 방법
알겠습니다. 첫째, 바이트 코드, 즉 16진 바이트를 박리하고, 조작 코드와 파라미터를 표시합니다. 둘째, 우리는
CodeType
이 있습니다. 파이톤의 데이터 형식은 우리가 적합하고 사용할 수 있는 바이트 코드를 만드는 데 도움을 줍니다.마찬가지로 조립을 위해서, 당신은 어떻게 어셈블리를 하는지 알아야 합니다. 우리는 모듈 dis을 사용할 것입니다. 이 모듈은 어셈블리 함수, 파일, 코드에 사용됩니다.import dis
def sum (x, y):
return x + y
dis.dis (sum)
이 코드의 출력은 다음과 같다1. 4 0 LOAD_FAST 0 (x)
2. 2 LOAD_FAST 1 (y)
3. 4 BINARY_ADD
4. 6 RETURN_VALUE
>>>
보시다시피 이 모든 것은 바이트 코드입니다. 지금은 설명입니다.보시다시피, 더 쉽게 설명할 수 있도록 출력의 줄을 열거했습니다.
파이톤의 모든 지령은 특정한 조작 코드(조작 코드)가 있다. 이 예에서 우리는 3
LOAD_FAST BINARY_ADD RETURN_VALUE
을 사용하고 각 지령의 역할을 설명할 것이다.x
과 y
을 불러오고 싶지 않습니다.".그래, 순서대로 대답할게.
0 (x)
과 (y)
). *우리는 어떻게 함수를 다시 만들어서 바이트 코드로 만듭니까?
우리가 해야 할 첫 번째 일은 [types] 모듈(https://docs.python.org/3/library/types.html#module-types)에서
CodeType
과 FunctionType
을 가져오는 것이다.import dis
from types import CodeType, FunctionType
def sum (x, y):
return x + y
이후, 우리는 목표 코드를 만들 것이다활용단어참조
import dis
from types import CodeType, FunctionType
def sum (x, y):
return x + y
# This will be explained later, these are flags
CO_OPTIMIZED = 0x0001
CO_NEWLOCALS = 0x0002
CO_NOFREE = 0x0002
my_code = CodeType (
2, #argcount
0, #kwonlyargcount
2, #nlocals
2, #stacksize
(CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE), #flags
bytes ([124, 0, 124, 1, 23, 0, 83, 0]), #codestring
(0,), #constants
(), # names of constants or global (names)
('x', 'y',), #variable names (varnames)
'blog_no_name', #filename
'crafted_sum', #name (code name / function)
9, #Firstlineno (First line where this code appears)
b'', #lnotab
(), #freevars
(), # freecellvars
)
_sum = FunctionType (my_code, {})
result = _sum (213,3)
print (result)
# Expected output
# 216
그래 그래...많은 새로운 사물이 출현했으니, 우리는 지금 이 논점들을 해석할 것이다.CodeType: argcount, kwonlyargcount, nlocals, stacksize, flags, codestring, constants, names, varnames, filename, name, firstlineno, lnotab, freevars, freecellvars
논쟁하다묘사
argcount
매개변수 수
kwonlyargcount
키워드 매개변수 수
nlocals
국부 변수의 수량 (이 예에서 2, x, y)
스택 크기
스택의 최대 바이트 크기(이 경우 XY는 스택 프레임에 두 개의 공백이 필요하므로 2입니다.)
깃발
이 표지들은 바이트 코드의 일부 조건을 결정합니다. 당신은 이 reference 에 따라 지도할 수 있습니다.우리는 더욱 높은 교과서에서 깃발을 깊이 연구할 것이다.
코드 열
이것은 124에서 LOAD F.A.S.T., 23 BINARY ADD 및 83 RETURN VALUE를 의미하는 관련 시퀀스가 포함된 바이트 목록(배열)입니다.
상수
정수, False, True, 내장 함수와 같은 상수 값이 포함된 원조
성함
상수 이름을 포함하는 모듈
varnames
로컬 변수 이름
파일 이름
이 문자열은 파일 이름을 나타냅니다. 이 값을 사용하지 않을 때는 모든 문자열이 될 수 있습니다
성함
코드 객체 또는 함수의 이름
일선 번호
실행 코드의 첫 줄을 표시합니다. 파일을 가져오면 이것과 관련이 있습니다. 그렇지 않으면 정수일 수 있습니다.
나타브
이것은 바이트 대상의 편이량과 줄의 편이량 사이의 매핑입니다. 줄에 정보를 추가하지 않으려면
b''
을 사용하십시오프리바
나는 고급 강좌에서 이 변수들을 설명할 것이다. 이것은 패키지를 닫는 데 쓰일 것이다
cellvars
이 변수는 패키지에서 정의됩니다
FunctionType
으로 넘어가기 전에 주의해야 할 마지막 두 가지는 첫 번째는 조작 코드 뒤의 0*이다. 예를 들어 [124, 0,...] *두 번째는 각 바이트 코드가 버전에 따라 다를 수 있으므로 코드 문자열의 방향을 파악하거나 확인하려면 아래 snippet을 사용하십시오def sum (x, y):
return x + y
sum.__ code __.co_code
# Expected output in Python 3.7.9 (The version I use)
# b '|\x00|\x01\x17\x00S\x00'
# The bytes are interpreted as characters, probably to make it more readable. (If we put chr (124) it will print the character |)
제조 기능
이제 FunctionType을 사용합니다.
FunctionType: code, globals, name, argdefs, closure
논쟁하다묘사
비밀 번호
대상 코드(osea, 코드 유형)
글로벌
전역 변수를 포함하는 사전입니다. '{"Name: Value Name}' 이렇게 하면 Name은 식별자가 되고 접근 변수처럼 접근합니다.
이름(옵션)
객체 코드 값 덮어쓰기)
argdefs(선택 사항)
기본 매개 변수 값을 지정하는 모듈
닫기(옵션)
하나의 모듈이freevars에 연결을 제공합니다
좋습니다. 일단 명확해지면, 목표 코드 (
my_code
) 가 있는FunctionType을 추가하고 호출하기만 하면 됩니다.import dis
from types import CodeType, FunctionType
def sum (x, y):
return x + y
이후, 우리는 목표 코드를 만들 것이다import dis
from types import CodeType, FunctionType
def sum (x, y):
return x + y
# This I will explain later, they are flags
CO_OPTIMIZED = 0x0001
CO_NEWLOCALS = 0x0002
CO_NOFREE = 0x0002
my_code = CodeType (
2, #argcount
0, #kwonlyargcount
2, #nlocals
2, #stacksize
(CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE), #flags
bytes ([124, 0, 124, 1, 23, 0, 83, 0]), #codestring
(0,), #constants
(), # names of constants or global (names)
('x', 'y',), #variable names (varnames)
'blog_no_name', #filename
'crafted_sum', #name (code / function name)
9, #Firstlineno (First line where this code appears)
b '', #lnotab
(), #freevars
(), # freecellvars
)
_sum = FunctionType (my_code, {})
result = _sum (213,3)
print (result)
# Expected output
# 216
지금 이 정도입니다. 잠시 후에 다른 강좌를 올리겠습니다. 설명 closures출처
Reference
이 문제에 관하여(python에서 원시 바이트 코드를 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/torswq/how-to-create-raw-bytecode-i-299f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)