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
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
本文地址:
/show-274861.html
版权声明:除非特别标注原创,其它均来自互联网,转载时请以链接形式注明文章出处。