Python 가상 머신에서 Code 객체의 역할은 무엇입니까?
코드 객체 데이터 구조
typedef struct { PyObject_HEAD int co_argcount; /* #arguments, except *args */ int co_kwonlyargcount; /* #keyword only arguments */ int co_nlocals; /* #local variables */ int co_stacksize; /* #entries needed for evaluation stack */ int co_flags; /* CO_..., see below */ PyObject *co_code; /* instruction opcodes */ PyObject *co_consts; /* list (constants used) */ PyObject *co_names; /* list of strings (names used) */ PyObject *co_varnames; /* tuple of strings (local variable names) */ PyObject *co_freevars; /* tuple of strings (free variable names) */ PyObject *co_cellvars; /* tuple of strings (cell variable names) */ /* The rest aren't used in either hash or comparisons, except for co_name (used in both) and co_firstlineno (used only in comparisons). This is done to preserve the name and line number for tracebacks and debuggers; otherwise, constant de-duplication would collapse identical functions/lambdas defined on different lines. */ unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ int co_firstlineno; /* first source line number */ PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See Objects/lnotab_notes.txt for details. */ void *co_zombieframe; /* for optimization only (see frameobject.c) */ PyObject *co_weakreflist; /* to support weakrefs to code objects */ } PyCodeObject;
다음은 코드 객체의 각 필드의 역할입니다.
우선 코드 블록이라는 개념을 이해해야 합니다. , 전체적으로 작은 단위로 실행됩니다. Python의 일반적인 코드 블록에는 함수 본문, 클래스 정의 및 모듈이 포함됩니다.
argcount는 코드 블록의 매개변수 수를 나타냅니다. 이 매개변수는 함수 본문 코드 블록에만 유용합니다. 예를 들어 위의 pycdemo.py는 함수가 아닌 모듈입니다. 이므로 이 매개변수의 해당 값은 0입니다.
co_code, 이 개체의 특정 콘텐츠는 실제 Python 바이트코드를 저장하는 바이트 시퀀스입니다. 이는 주로 Python 가상 머신 실행에 사용되며 이 기사에서는 자세히 분석하지 않습니다.
co_consts, 이 필드는 목록 유형 필드로, 주로 위의 "__main__" 및 100과 같은 일부 문자열 상수와 숫자 상수를 포함합니다.
co_filename, 이 필드의 의미는 해당 소스 파일의 파일 이름입니다.
co_firstlineno, 이 필드의 의미는 Python 소스 파일의 코드 첫 번째 줄에 나타나는 줄 수입니다. 이 필드는 디버깅할 때 매우 중요합니다.
co_flags, 이 필드의 주요 의미는 이 코드 개체의 유형을 식별하는 것입니다. 0x0080은 이 블록이 코루틴임을 나타내고, 0x0010은 이 코드 객체가 중첩되었음을 나타냅니다.
co_lnotab, 이 필드의 의미는 주로 각 바이트코드 명령어에 해당하는 소스 코드 줄 수를 계산하는 데 사용됩니다.
co_varnames, 이 필드의 주요 의미는 코드 개체에서 로컬로 정의된 이름을 나타내는 것입니다. co_varnames의 반대인
co_names는 로컬로 정의되지 않고 코드 개체에 사용되는 이름을 나타냅니다.
co_nlocals, 이 필드는 코드 객체에서 로컬로 사용되는 변수의 수를 나타냅니다.
co_stackszie, Python 가상 머신은 스택 컴퓨터이므로 이 매개변수의 값은 이 스택에 필요한 최대값을 나타냅니다.
co_cellvars, co_freevars, 이 두 필드는 주로 중첩 함수 및 함수 클로저와 관련이 있습니다. 이 필드에 대해서는 후속 기사에서 자세히 설명하겠습니다.
CodeObject 상세 분석
이제 몇 가지 실용적인 예를 사용하여 특정 코드 개체를 분석합니다.
import dis import binascii import types d = 10 def test_co01(c): a = 1 b = 2 return a + b + c + d
이전 기사에서 함수에 코드 개체 개체가 포함되어 있다고 언급했습니다. test_co01의 코드 개체 개체(전체 코드는 co01 참조)의 출력 결과는 다음과 같습니다.
code argcount 1 nlocals 3 stacksize 2 flags 0043 0x43 code b'6401007d01006402007d02007c01007c0200177c0000177400001753' 9 0 LOAD_CONST 1 (1) 3 STORE_FAST 1 (a) 10 6 LOAD_CONST 2 (2) 9 STORE_FAST 2 (b) 11 12 LOAD_FAST 1 (a) 15 LOAD_FAST 2 (b) 18 BINARY_ADD 19 LOAD_FAST 0 (c) 22 BINARY_ADD 23 LOAD_GLOBAL 0 (d) 26 BINARY_ADD 27 RETURN_VALUE consts None 1 2 names ('d',) varnames ('c', 'a', 'b') freevars () cellvars () filename '/tmp/pycharm_project_396/co01.py' name 'test_co01' firstlineno 8 lnotab b'000106010601'
필드 값 argcount는 1과 같습니다. 이는 함수에 하나의 매개변수가 있고 이 함수 test_co01에는 서로 대응하는 매개변수 c가 있음을 나타냅니다.
nlocals 필드의 값은 3으로, 총 3개의 함수 로컬 변수 a, b, c가 test_co01 함수에 구현되어 있음을 나타냅니다.
필드 이름은 코드의 co_names에 해당합니다. 이전 정의에 따르면 전역 변수 d는 test_co01 함수에서 사용되지만 함수에서는 정의되지 않습니다.
Field varnames는 로컬 정의에 사용되는 변수를 나타냅니다. test_co01 함수에는 a, b, c 세 가지 주요 변수가 있습니다.
필드 파일 이름은 Python 파일의 주소입니다.
Field firstlineno는 함수의 첫 번째 줄이 해당 Python 코드의 8번째 줄에 나타남을 나타냅니다.
Flags 필드 상세 분석
분석을 위해 특별히 python3.5의 소스 코드를 사용합니다. cpython 가상 머신의 구체적인 구현은 다음과 같습니다(Include/code.h):
/* Masks for co_flags above */ #define CO_OPTIMIZED 0x0001 #define CO_NEWLOCALS 0x0002 #define CO_VARARGS 0x0004 #define CO_VARKEYWORDS 0x0008 #define CO_NESTED 0x0010 #define CO_GENERATOR 0x0020 /* The CO_NOFREE flag is set if there are no free or cell variables. This information is redundant, but it allows a single flag test to determine whether there is any extra work to be done when the call frame it setup. */ #define CO_NOFREE 0x0040 /* The CO_COROUTINE flag is set for coroutine functions (defined with ``async def`` keywords) */ #define CO_COROUTINE 0x0080 #define CO_ITERABLE_COROUTINE 0x0100
플래그 필드와 위의 각 매크로 정의는 & 연산을 수행하여 결과가 0보다 크면 해당 조건이 충족되었음을 의미합니다.
위 매크로 정의의 의미는 다음과 같습니다.
CO_OPTIMIZED 이 필드는 코드 개체가 최적화되었으며 함수에 의해 로컬로 정의된 변수를 사용함을 나타냅니다.
CO_NEWLOCALS, 이 필드의 의미는 이 코드 객체의 코드가 실행될 때 스택 프레임의 f_locals 객체에 대해 dict 객체가 생성된다는 것입니다.
CO_VARARGS - 이 코드 객체에 위치 매개변수가 포함되어 있는지 여부를 나타냅니다.
CO_VARKEYWORDS - 이 코드 객체에 키워드 매개변수가 포함되어 있는지 여부를 나타냅니다.
CO_NESTED, 이 코드 객체가 중첩 함수임을 나타냅니다.
CO_GENERATOR은 이 코드 객체가 생성기임을 나타냅니다.
CO_COROUTINE은 이 코드 객체가 코루틴 함수임을 나타냅니다.
CO_ITERABLE_COROUTINE은 코드 객체가 반복 가능한 코루틴 함수임을 나타냅니다.
CO_NOFREE 이는 freevar 및 cellvar가 없음, 즉 함수 폐쇄가 없음을 의미합니다.
이제 이전 함수 test_co01의 플래그를 분석해 보겠습니다. 해당 값은 0x43입니다. 이는 이 함수가 CO_NEWLOCALS, CO_OPTIMIZED 및 CO_NOFREE의 세 가지 특성을 충족한다는 의미입니다.
freevars & cellvars
我们使用下面的函数来对这两个字段进行分析:
def test_co02(): a = 1 b = 2 def g(): return a + b return a + b + g()
上面的函数的信息如下所示(完整代码见co02):
code argcount 0 nlocals 1 stacksize 3 flags 0003 0x3 code b'640100890000640200890100870000870100660200640300640400860000' b'7d0000880000880100177c00008300001753' 15 0 LOAD_CONST 1 (1) 3 STORE_DEREF 0 (a) 16 6 LOAD_CONST 2 (2) 9 STORE_DEREF 1 (b) 18 12 LOAD_CLOSURE 0 (a) 15 LOAD_CLOSURE 1 (b) 18 BUILD_TUPLE 2 21 LOAD_CONST 3 (<code object g at 0x7f133ff496f0, file "/tmp/pycharm_project_396/co01.py", line 18>) 24 LOAD_CONST 4 ('test_co02.<locals>.g') 27 MAKE_CLOSURE 0 30 STORE_FAST 0 (g) 20 33 LOAD_DEREF 0 (a) 36 LOAD_DEREF 1 (b) 39 BINARY_ADD 40 LOAD_FAST 0 (g) 43 CALL_FUNCTION 0 (0 positional, 0 keyword pair) 46 BINARY_ADD 47 RETURN_VALUE consts None 1 2 code argcount 0 nlocals 0 stacksize 2 flags 0013 0x13 code b'8800008801001753' 19 0 LOAD_DEREF 0 (a) 3 LOAD_DEREF 1 (b) 6 BINARY_ADD 7 RETURN_VALUE consts None names () varnames () freevars ('a', 'b') cellvars () filename '/tmp/pycharm_project_396/co01.py' name 'g' firstlineno 18 lnotab b'0001' 'test_co02.<locals>.g' names () varnames ('g',) freevars () cellvars ('a', 'b') filename '/tmp/pycharm_project_396/co01.py' name 'test_co02' firstlineno 14 lnotab b'0001060106021502'
从上面的输出我们可以看到的是,函数 test_co02 的 cellvars 为 ('a', 'b'),函数 g 的 freevars 为 ('a', 'b'),cellvars 表示在其他函数当中会使用本地定义的变量,freevars 表示本地会使用其他函数定义的变量。
再来分析一下函数 test_co02 的 flags,他的 flags 等于 0x3 因为有闭包的存在因此 flags 不会存在 CO_NOFREE,也就是少了值 0x0040 。
stacksize
这个字段存储的是在函数在被虚拟机执行的时候所需要的最大的栈空间的大小,这也是一种优化手段,因为在知道所需要的最大的栈空间,所以可以在函数执行的时候直接分配指定大小的空间不需要在函数执行的时候再去重新扩容。
def test_stack(): a = 1 b = 2 return a + b
上面的代码相关字节码等信息如下所示:
code argcount 0 nlocals 2 stacksize 2 flags 0043 0x43 code b'6401007d00006402007d01007c00007c01001753' # 字节码指令 # 字节码指令参数 # 参数对应的值 24 0 LOAD_CONST 1 (1) 3 STORE_FAST 0 (a) 25 6 LOAD_CONST 2 (2) 9 STORE_FAST 1 (b) 26 12 LOAD_FAST 0 (a) 15 LOAD_FAST 1 (b) 18 BINARY_ADD 19 RETURN_VALUE consts None # 下标等于 0 的常量 1 # 下标等于 1 的常量 2 # 下标等于 2 的常量 names () varnames ('a', 'b') freevars () cellvars ()
我们现在来模拟一下执行过程,在模拟之前我们首先来了解一下上面几条字节码的作用:
LOAD_CONST,将常量表当中的下标等于 i 个对象加载到栈当中,对应上面的代码 LOAD_CONST 的参数 i = 1。因此加载测常量等于 1 。因此现在栈空间如下所示:
STORE_FAST,将栈顶元素弹出并且保存到 co_varnames 对应的下标当中,根据上面的字节码参数等于 0 ,因此将 1 保存到 co_varnames[0] 对应的对象当中。
LOAD_CONST,将下标等于 2 的常量加载进入栈中。
STORE_FAST,将栈顶元素弹出,并且保存到 varnames 下标为 1 的对象。
LOAD_FAST,是取出 co_varnames 对应下标的数据,并且将其压入栈中。我们直接连续执行两个 LOAD_FAST 之后栈空间的布局如下:
BINARY_ADD,这个字节码指令是将栈空间的两个栈顶元素弹出,然后将两个数据进行相加操作,然后将相加得到的结果重新压入栈中。
RETURN_VALUE,将栈顶元素弹出并且作为返回值返回。
从上面的整个执行过程来看整个栈空间使用的最大的空间长度为 2 ,因此 stacksize = 2 。
위 내용은 Python 가상 머신에서 Code 객체의 역할은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HADIDB : 가볍고 높은 수준의 확장 가능한 Python 데이터베이스 HadIDB (HADIDB)는 파이썬으로 작성된 경량 데이터베이스이며 확장 수준이 높습니다. PIP 설치를 사용하여 HADIDB 설치 : PIPINSTALLHADIDB 사용자 관리 사용자 만들기 사용자 : createUser () 메소드를 작성하여 새 사용자를 만듭니다. Authentication () 메소드는 사용자의 신원을 인증합니다. Fromhadidb.operationimportuseruser_obj = user ( "admin", "admin") user_obj.

해시 값으로 저장되기 때문에 MongoDB 비밀번호를 Navicat을 통해 직접 보는 것은 불가능합니다. 분실 된 비밀번호 검색 방법 : 1. 비밀번호 재설정; 2. 구성 파일 확인 (해시 값이 포함될 수 있음); 3. 코드를 점검하십시오 (암호 하드 코드 메일).

Python은 웹 개발, 데이터 과학, 기계 학습, 자동화 및 스크립팅 분야에서 널리 사용됩니다. 1) 웹 개발에서 Django 및 Flask 프레임 워크는 개발 프로세스를 단순화합니다. 2) 데이터 과학 및 기계 학습 분야에서 Numpy, Pandas, Scikit-Learn 및 Tensorflow 라이브러리는 강력한 지원을 제공합니다. 3) 자동화 및 스크립팅 측면에서 Python은 자동화 된 테스트 및 시스템 관리와 같은 작업에 적합합니다.

2 시간 이내에 Python의 기본 프로그래밍 개념과 기술을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우기, 2. 마스터 제어 흐름 (조건부 명세서 및 루프), 3. 기능의 정의 및 사용을 이해하십시오. 4. 간단한 예제 및 코드 스 니펫을 통해 Python 프로그래밍을 신속하게 시작하십시오.

MySQL 데이터베이스 성능 최적화 안내서 리소스 집약적 응용 프로그램에서 MySQL 데이터베이스는 중요한 역할을 수행하며 대규모 트랜잭션 관리를 담당합니다. 그러나 응용 프로그램 규모가 확장됨에 따라 데이터베이스 성능 병목 현상은 종종 제약이됩니다. 이 기사는 일련의 효과적인 MySQL 성능 최적화 전략을 탐색하여 응용 프로그램이 고 부하에서 효율적이고 반응이 유지되도록합니다. 실제 사례를 결합하여 인덱싱, 쿼리 최적화, 데이터베이스 설계 및 캐싱과 같은 심층적 인 주요 기술을 설명합니다. 1. 데이터베이스 아키텍처 설계 및 최적화 된 데이터베이스 아키텍처는 MySQL 성능 최적화의 초석입니다. 몇 가지 핵심 원칙은 다음과 같습니다. 올바른 데이터 유형을 선택하고 요구 사항을 충족하는 가장 작은 데이터 유형을 선택하면 저장 공간을 절약 할 수있을뿐만 아니라 데이터 처리 속도를 향상시킬 수 있습니다.

데이터 전문가는 다양한 소스에서 많은 양의 데이터를 처리해야합니다. 이것은 데이터 관리 및 분석에 어려움을 겪을 수 있습니다. 다행히도 AWS Glue와 Amazon Athena의 두 가지 AWS 서비스가 도움이 될 수 있습니다.

아니요, MySQL은 SQL Server에 직접 연결할 수 없습니다. 그러나 다음 방법을 사용하여 데이터 상호 작용을 구현할 수 있습니다. 미들웨어 사용 : MySQL에서 중간 형식으로 데이터를 내보낸 다음 미들웨어를 통해 SQL Server로 가져옵니다. 데이터베이스 링커 사용 : 비즈니스 도구는 본질적으로 미들웨어를 통해 여전히 구현되는보다 우호적 인 인터페이스와 고급 기능을 제공합니다.

Redis 서버를 시작하는 단계에는 다음이 포함됩니다. 운영 체제에 따라 Redis 설치. Redis-Server (Linux/MacOS) 또는 Redis-Server.exe (Windows)를 통해 Redis 서비스를 시작하십시오. Redis-Cli Ping (Linux/MacOS) 또는 Redis-Cli.exe Ping (Windows) 명령을 사용하여 서비스 상태를 확인하십시오. Redis-Cli, Python 또는 Node.js와 같은 Redis 클라이언트를 사용하여 서버에 액세스하십시오.
