首页 > 解决方案 > 当函数的 __qualname__ 在 python 中更改时会发生什么?

问题描述

为了能够腌制嵌套函数(用于多处理),我用装饰器装饰了嵌套函数:

def globalize_one(func):
    def wrapper_one(*args,**kwargs):
        return func(*args,**kwargs)
    setattr(modules['__main__'],'sdfsdf',wrapper_one)
    return wrapper_one

但是,当我运行它时,这个装饰器不起作用

def test_one():
    @globalize_one
    def inside_one():
        return 1

    try:
        pickle.dumps(inside_one)
    except Exception as e:
        print(e)

test_one()

我收到了异常Can't pickle local object 'globalize_one.<locals>.wrapper_one'

为了让装饰器工作,我只需要在行之前将__qualname__of更改wrapper_onesdfsdfglobalize_onesetattr(modules['__main__'],'sdfsdf',wrapper_one)

def globalize_two(func):
    def wrapper_two(*args,**kwargs):
        return func(*args,**kwargs)

    # the single extra line as compared to globalize_one
    wrapper_two.__qualname__ = 'sdfsdf'

    setattr(modules['__main__'],'sdfsdf',wrapper_two)
    return wrapper_two

def test_two():
    @globalize_two
    def inside_two():
        return 1

    try:
        pickle.dumps(inside_two)
    except Exception as e:
        print(e)

通过运行代码可以看到,嵌套函数inside_two现在可以腌制了。

我的困惑是,为什么通过更改__qualname__,装饰器会正常工作?我认为更改函数的名称没有实际效果。

标签: pythonpickle

解决方案


推荐阅读