찾다
백엔드 개발파이썬 튜토리얼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&#39;6401007d01006402007d02007c01007c0200177c0000177400001753&#39;
  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 (&#39;d&#39;,)
   varnames (&#39;c&#39;, &#39;a&#39;, &#39;b&#39;)
   freevars ()
   cellvars ()
   filename &#39;/tmp/pycharm_project_396/co01.py&#39;
   name &#39;test_co01&#39;
   firstlineno 8
   lnotab b&#39;000106010601&#39;
  • 필드 값 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&#39;640100890000640200890100870000870100660200640300640400860000&#39;
      b&#39;7d0000880000880100177c00008300001753&#39;
 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 (&#39;test_co02.<locals>.g&#39;)
             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&#39;8800008801001753&#39;
 19           0 LOAD_DEREF               0 (a)
              3 LOAD_DEREF               1 (b)
              6 BINARY_ADD
              7 RETURN_VALUE
         consts
            None
         names ()
         varnames ()
         freevars (&#39;a&#39;, &#39;b&#39;)
         cellvars ()
         filename &#39;/tmp/pycharm_project_396/co01.py&#39;
         name &#39;g&#39;
         firstlineno 18
         lnotab b&#39;0001&#39;
      &#39;test_co02.<locals>.g&#39;
   names ()
   varnames (&#39;g&#39;,)
   freevars ()
   cellvars (&#39;a&#39;, &#39;b&#39;)
   filename &#39;/tmp/pycharm_project_396/co01.py&#39;
   name &#39;test_co02&#39;
   firstlineno 14
   lnotab b&#39;0001060106021502&#39;

从上面的输出我们可以看到的是,函数 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&#39;6401007d00006402007d01007c00007c01001753&#39;
   #					  字节码指令		 # 字节码指令参数 # 参数对应的值
 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 (&#39;a&#39;, &#39;b&#39;)
   freevars ()
   cellvars ()

我们现在来模拟一下执行过程,在模拟之前我们首先来了解一下上面几条字节码的作用:

LOAD_CONST,将常量表当中的下标等于 i 个对象加载到栈当中,对应上面的代码 LOAD_CONST 的参数 i = 1。因此加载测常量等于 1 。因此现在栈空间如下所示:

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

STORE_FAST,将栈顶元素弹出并且保存到 co_varnames 对应的下标当中,根据上面的字节码参数等于 0 ,因此将 1 保存到 co_varnames[0] 对应的对象当中。

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

LOAD_CONST,将下标等于 2 的常量加载进入栈中。

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

STORE_FAST,将栈顶元素弹出,并且保存到 varnames 下标为 1 的对象。

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

LOAD_FAST,是取出 co_varnames 对应下标的数据,并且将其压入栈中。我们直接连续执行两个 LOAD_FAST 之后栈空间的布局如下:

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

BINARY_ADD,这个字节码指令是将栈空间的两个栈顶元素弹出,然后将两个数据进行相加操作,然后将相加得到的结果重新压入栈中。

Python 가상 머신에서 Code 객체의 역할은 무엇입니까?

RETURN_VALUE,将栈顶元素弹出并且作为返回值返回。

从上面的整个执行过程来看整个栈空间使用的最大的空间长度为 2 ,因此 stacksize = 2 。

위 내용은 Python 가상 머신에서 Code 객체의 역할은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 亿速云에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
파이썬 : 게임, Guis 등파이썬 : 게임, Guis 등Apr 13, 2025 am 12:14 AM

Python은 게임 및 GUI 개발에서 탁월합니다. 1) 게임 개발은 Pygame을 사용하여 드로잉, 오디오 및 기타 기능을 제공하며 2D 게임을 만드는 데 적합합니다. 2) GUI 개발은 Tkinter 또는 PYQT를 선택할 수 있습니다. Tkinter는 간단하고 사용하기 쉽고 PYQT는 풍부한 기능을 가지고 있으며 전문 개발에 적합합니다.

Python vs. C : 응용 및 사용 사례가 비교되었습니다Python vs. C : 응용 및 사용 사례가 비교되었습니다Apr 12, 2025 am 12:01 AM

Python은 데이터 과학, 웹 개발 및 자동화 작업에 적합한 반면 C는 시스템 프로그래밍, 게임 개발 및 임베디드 시스템에 적합합니다. Python은 단순성과 강력한 생태계로 유명하며 C는 고성능 및 기본 제어 기능으로 유명합니다.

2 시간의 파이썬 계획 : 현실적인 접근2 시간의 파이썬 계획 : 현실적인 접근Apr 11, 2025 am 12:04 AM

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

파이썬 : 기본 응용 프로그램 탐색파이썬 : 기본 응용 프로그램 탐색Apr 10, 2025 am 09:41 AM

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

2 시간 안에 얼마나 많은 파이썬을 배울 수 있습니까?2 시간 안에 얼마나 많은 파이썬을 배울 수 있습니까?Apr 09, 2025 pm 04:33 PM

2 시간 이내에 파이썬의 기본 사항을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우십시오. 이를 통해 간단한 파이썬 프로그램 작성을 시작하는 데 도움이됩니다.

10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법?10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법?Apr 02, 2025 am 07:18 AM

10 시간 이내에 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법은 무엇입니까? 컴퓨터 초보자에게 프로그래밍 지식을 가르치는 데 10 시간 밖에 걸리지 않는다면 무엇을 가르치기로 선택 하시겠습니까?

중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까?중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까?Apr 02, 2025 am 07:15 AM

Fiddlerevery Where를 사용할 때 Man-in-the-Middle Reading에 Fiddlereverywhere를 사용할 때 감지되는 방법 ...

Python 3.6에 피클 파일을로드 할 때 '__builtin__'모듈을 찾을 수없는 경우 어떻게해야합니까?Python 3.6에 피클 파일을로드 할 때 '__builtin__'모듈을 찾을 수없는 경우 어떻게해야합니까?Apr 02, 2025 am 07:12 AM

Python 3.6에 피클 파일로드 3.6 환경 보고서 오류 : modulenotfounderror : nomodulename ...

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

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

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기