python使用代码修改函数内部的变量名

def test():
    a = 100
    print(a)

装饰器可以给函数增加功能,那如果需要使用代码把函数内的a=100变成b=99,然后print(b),有办法可以实现吗?

阅读 2.3k
2 个回答

当然可以。

为了更好的查看效果,原函数改成

def example():
    a = 100
    print(locals())

查看函数的 Bytecode 实现,用 dis.dis(example),输出

指令位置指令参数索引参数值
340LOAD_CONST1100
2STORE_FAST0a
354LOAD_GLOBAL0print
6LOAD_GLOBAL1locals
8CALL_FUNCTION0
10CALL_FUNCTION1
12POP_TOP
14LOAD_CONST0None
16RETURN_VALUE

只需要修改

  1. co_consts[1] 为 99
  2. co_varnames[0] 为 'b'

代码如下

import dis
import types


def modify(f):
    c = f.__code__
    consts = list(c.co_consts)
    consts[1] = 99

    varnames = list(c.co_varnames)
    varnames[0] = 'b'
    f.__code__ = types.CodeType(
        c.co_argcount,
        c.co_kwonlyargcount,
        c.co_nlocals,
        c.co_stacksize,
        c.co_flags,
        c.co_code,
        tuple(consts),
        c.co_names,
        tuple(varnames),
        c.co_filename,
        c.co_name,
        c.co_firstlineno,
        c.co_lnotab,
        c.co_freevars,
        c.co_cellvars,
    )
    return f


def example():
    a = 100
    print(locals())


@modify
def example2():
    a = 100
    print(locals())


example()
# dis.dis(example)
example2()
# dis.dis(example2)

装饰器的本质是装饰,扩展,添加之意,并不变更原有的代码逻辑

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏