コード オブジェクトのデータ構造
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 コードが小さな単位として実行されます。 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_names は co_varnames の逆で、ローカルに定義されていないがコード オブジェクトで使用される名前を表します。
co_nlocals、このフィールドは、コード オブジェクト内でローカルに使用される変数の数を示します。
co_stackszie、Python 仮想マシンはスタック コンピューターであるため、このパラメーターの値は、このスタックに必要な最大値を示します。
co_cellvars、co_freevars、これら 2 つのフィールドは主にネストされた関数と関数クロージャに関連しています。このフィールドについては後続の記事で詳しく説明します。
コードオブジェクトの詳細な分析
次に、いくつかの実践的な例を使用して、特定のコード オブジェクトを分析します。
import dis import binascii import types d = 10 def test_co01(c): a = 1 b = 2 return a + b + c + d
前の記事では、関数にはコード オブジェクト オブジェクトが含まれると述べましたが、test_co01 (完全なコードについては co01 を参照) のコード オブジェクト オブジェクトの出力結果は次のとおりです。
- #フィールド argcount の値は 1 に等しく、関数が 1 つのパラメーターを持つことを示します。この関数 test_co01 には、互いに対応するパラメーター c があります。
- フィールド nlocals の値は 3 に等しく、合計 3 つの関数ローカル変数 a、b、c が関数 test_co01 に実装されていることを示します。
- フィールド名はコード内の co_names に対応します。前の定義によれば、グローバル変数 d は関数 test_co01 で使用されていますが、関数内では定義されていません。
- フィールド変数名、これはローカル定義で使用される変数を表します。関数 test_co01 には 3 つの主要な変数 a、b、c があります。
- フィールド filename は、Python ファイルのアドレスです。
- フィールド firstlineno は、関数の最初の行が、対応する Python コードの 8 行目に現れることを示します。
- Flags フィールドの詳細な分析
分析には特に python3.5 のソース コードを使用します。cpython 仮想マシンの具体的な実装は次のとおりです (インクルード/コード) .h ):
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'
flags フィールドと上記の各マクロ定義の間で & 演算が実行され、結果が 0 より大きい場合、対応する条件が満たされていることを意味します。
上記のマクロ定義の意味は次のとおりです:
- CO_OPTIMIZED
、このフィールドは、関数ローカルを使用してコード オブジェクトが最適化されていることを示します。定義された変数。
- CO_NEWLOCALS
、このフィールドの意味は、このコード オブジェクトのコードが実行されると、スタック内の f_locals オブジェクトの dict オブジェクトが作成されることです。フレーム。
- CO_VARARGS
は、このコード オブジェクトに位置パラメータが含まれるかどうかを示します。
- CO_VARKEYWORDS
は、このコード オブジェクトにキーワード パラメーターが含まれているかどうかを示します。
- CO_NESTED
、このコード オブジェクトがネストされた関数であることを示します。
- CO_GENERATOR
、このコード オブジェクトがジェネレーターであることを示します。
- CO_COROUTINE
。このコード オブジェクトがコルーチン関数であることを示します。
- CO_ITERABLE_COROUTINE
。コード オブジェクトが反復可能なコルーチン関数であることを示します。
- CO_NOFREE
、これは、freevars と cellvars がないこと、つまり関数クロージャーがないことを意味します。
次に、前の関数 test_co01 のフラグを分析しましょう。その対応する値は 0x43 に等しく、これは、この関数が 3 つの特性 (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 仮想マシンにおけるコード オブジェクトの役割は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

PythonはゲームとGUI開発に優れています。 1)ゲーム開発は、2Dゲームの作成に適した図面、オーディオ、その他の機能を提供し、Pygameを使用します。 2)GUI開発は、TKINTERまたはPYQTを選択できます。 TKINTERはシンプルで使いやすく、PYQTは豊富な機能を備えており、専門能力開発に適しています。

Pythonは、データサイエンス、Web開発、自動化タスクに適していますが、Cはシステムプログラミング、ゲーム開発、組み込みシステムに適しています。 Pythonは、そのシンプルさと強力なエコシステムで知られていますが、Cは高性能および基礎となる制御機能で知られています。

2時間以内にPythonの基本的なプログラミングの概念とスキルを学ぶことができます。 1.変数とデータ型、2。マスターコントロールフロー(条件付きステートメントとループ)、3。機能の定義と使用を理解する4。

Pythonは、Web開発、データサイエンス、機械学習、自動化、スクリプトの分野で広く使用されています。 1)Web開発では、DjangoおよびFlask Frameworksが開発プロセスを簡素化します。 2)データサイエンスと機械学習の分野では、Numpy、Pandas、Scikit-Learn、Tensorflowライブラリが強力なサポートを提供します。 3)自動化とスクリプトの観点から、Pythonは自動テストやシステム管理などのタスクに適しています。

2時間以内にPythonの基本を学ぶことができます。 1。変数とデータ型を学習します。2。ステートメントやループの場合などのマスター制御構造、3。関数の定義と使用を理解します。これらは、簡単なPythonプログラムの作成を開始するのに役立ちます。

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

Python 3.6のピクルスファイルのロードレポートエラー:modulenotFounderror:nomodulenamed ...


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)
