{site_name}

{site_name}

🌜 搜索

PythonNew opcodes 是指在 Python 3.10 版本中新增的

Python 𝄐 0
python new object
PythonNew opcodes 是指在 Python 3.10 版本中新增的一组字节码操作码,它们被用于实现新的语言特性和优化现有功能。以下是其中一些 PythonNew opcodes 的解释和示例:

1. LOAD_METHOD:用于加载对象的方法,并将其推入栈顶。与旧版的 LOAD_ATTR 操作码不同之处在于,它可以直接读取类属性而无需通过实例。

示例代码:


class MyClass:
@staticmethod
def my_static_method(x):
return x**2

method = MyClass.my_static_method

# 使用 LOAD_METHOD 操作码获取静态方法
def f():
bytecode = bytes([
dis.opmap['LOAD_METHOD'], # 加载方法
0x00, # 内存地址 (MyClass.my_static_method)
dis.opmap['LOAD_CONST'], # 加载常量
0x01, # 常量表中的内存地址 (None)
dis.opmap['CALL_METHOD'], # 调用方法
0x00, # 参数数量 (1)
dis.opmap['POP_TOP'], # 弹出返回值
dis.opmap['LOAD_CONST'], # 加载常量
0x02, # 常量表中的内存地址 (None)
dis.opmap['RETURN_VALUE'], # 返回值
])
code = types.CodeType(
0, 0, 0, 0, bytecode, (), (), (), "", "", 0, b"")
func = types.FunctionType(code, {})

# 调用方法
func(3)

# 使用普通的属性访问方式获取静态方法
def g():
method(3)

f() # 输出 None
g() # 输出 9


2. CALL_FINALLY:用于在 try-finally 块中调用 finally 子句。与旧版的 POP_BLOCK 操作码不同之处在于,它可以确保 finally 子句一定会被执行。

示例代码:


try:
print("try")
finally:
print("finally")

# 使用 CALL_FINALLY 操作码模拟 try-finally 块
bytecode = bytes([
dis.opmap['SETUP_FINALLY'], # 设置 finally 块
0x0A, # 相对跳转位置 (10)
dis.opmap['LOAD_CONST'], # 加载常量
0x00, # 常量表中的内存地址 ("try")
dis.opmap['PRINT_ITEM'], # 打印 "try"
dis.opmap['POP_TOP'], # 弹出栈顶元素
dis.opmap['JUMP_FORWARD'], # 无条件跳转
0x07, # 相对跳转位置 (7)
dis.opmap['COME_FROM'], # 出口标记
dis.opmap['LOAD_CONST'], # 加载常量
0x01, # 常量表中的内存地址 ("finally")
dis.opmap['PRINT_ITEM'], # 打印 "finally"
dis.opmap['POP_TOP'], # 弹出栈顶元素
dis.opmap['LOAD_CONST'], # 加载常量
0x02, # 常量表中的内存地址 (None)
dis.opmap['CALL_FINALLY'], # 调用 finally 块
dis.opmap['RAISE_VARARGS'], # 抛出异常
0x01, # 参数数量 (1)
dis.opmap['LOAD_CONST'], # 加载常量
0x03, # 常量表中的内存地址 (None)
dis.opmap['RETURN_VALUE'], # 返回值
])
code = types.CodeType(
0, 0, 0, 0, bytecode, (), (), (), "", "", 0, b"")
func = types.FunctionType(code, {})

func() # 输出 "try" 和 "finally"


3. CALL_CODE:用于调用另一个函数的字节码。与旧版的 CALL_FUNCTION