我们从Python开源项目中,提取了以下3个代码示例,用于说明如何使用dis.haslocal()。
def parse_byte_and_args(self): code = self.f_code opcode = code.co_code[self.f_lasti] self.f_lasti = self.f_lasti + 1 if opcode >= dis.HAVE_ARGUMENT: int_arg = ( code.co_code[self.f_lasti] + (code.co_code[self.f_lasti+1] << 8)) self.f_lasti = self.f_lasti + 2 if opcode in dis.hasconst: arg = code.co_consts[int_arg] elif opcode in dis.hasfree: if int_arg < len(code.co_cellvars): arg = code.co_cellvars[int_arg] else: arg = code.co_freevars[int_arg - len(code.co_cellvars)] elif opcode in dis.hasname: arg = code.co_names[int_arg] elif opcode in dis.haslocal: arg = code.co_varnames[int_arg] elif opcode in dis.hasjrel: arg = self.f_lasti + int_arg else: arg = int_arg return dis.opname[opcode], (arg,) return dis.opname[opcode], ()
def parse_byte_and_args(self): """ Parse 1 - 3 bytes of bytecode into an instruction and optionally arguments.""" f = self.frame opoffset = f.f_lasti byteCode = ord(f.f_code.co_code[opoffset]) f.f_lasti += 1 byteName = dis.opname[byteCode] arg = None arguments = [] if byteCode >= dis.HAVE_ARGUMENT: arg = f.f_code.co_code[f.f_lasti:f.f_lasti+2] f.f_lasti += 2 intArg = ord(arg[0]) + (ord(arg[1]) << 8) if byteCode in dis.hasconst: arg = f.f_code.co_consts[intArg] elif byteCode in dis.hasfree: if intArg < len(f.f_code.co_cellvars): arg = f.f_code.co_cellvars[intArg] else: var_idx = intArg - len(f.f_code.co_cellvars) arg = f.f_code.co_freevars[var_idx] elif byteCode in dis.hasname: arg = f.f_code.co_names[intArg] elif byteCode in dis.hasjrel: arg = f.f_lasti + intArg elif byteCode in dis.hasjabs: arg = intArg elif byteCode in dis.haslocal: arg = f.f_code.co_varnames[intArg] else: arg = intArg arguments = [arg] return byteName, arguments, opoffset
def insert_code(code_to_modify, code_to_insert, before_line): """ Insert piece of code `code_to_insert` to `code_to_modify` right inside the line `before_line` before the instruction on this line by modifying original bytecode :param code_to_modify: Code to modify :param code_to_insert: Code to insert :param before_line: Number of line for code insertion :return: boolean flag whether insertion was successful, modified code """ linestarts = dict(dis.findlinestarts(code_to_modify)) if before_line not in linestarts.values(): return code_to_modify offset = None for off, line_no in linestarts.items(): if line_no == before_line: offset = off return_none_size = len(_return_none_fun.__code__.co_code) code_to_insert_obj = code_to_insert.co_code[:-return_none_size] try: code_to_insert_obj, new_names = \ _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_obj, 'co_names', dis.hasname) code_to_insert_obj, new_consts = \ _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_obj, 'co_consts', [opmap['LOAD_CONST']]) code_to_insert_obj, new_vars = \ _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_obj, 'co_varnames', dis.haslocal) new_bytes, all_inserted_code = _update_label_offsets(code_to_modify.co_code, offset, list(code_to_insert_obj)) new_lnotab = _modify_new_lines(code_to_modify, all_inserted_code) except ValueError: traceback.print_exc() return False, code_to_modify new_code = CodeType( code_to_modify.co_argcount, # integer code_to_modify.co_kwonlyargcount, # integer len(new_vars), # integer code_to_modify.co_stacksize, # integer code_to_modify.co_flags, # integer new_bytes, # bytes new_consts, # tuple new_names, # tuple new_vars, # tuple code_to_modify.co_filename, # string code_to_modify.co_name, # string code_to_modify.co_firstlineno, # integer new_lnotab, # bytes code_to_modify.co_freevars, # tuple code_to_modify.co_cellvars # tuple ) return True, new_code