您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python的types.FunctionType如何创建动态函数?

5b51 2022/1/14 8:21:35 python 字数 6701 阅读 521 来源 www.jb51.cc/python

我正在努力增强我的Python技能,我遇到了使用types.FunctionType的Open-Source code for Saltstack,我不明白发生了什么.salt.cloud.clouds.cloudstack.py函数create()包含以下代码:kwargs = { 'name': vm_['name'], 'image':

概述

我正在努力增强我的Python技能,我遇到了使用types.FunctionType的Open-Source code for Saltstack,我不明白发生了什么.

salt.cloud.clouds.cloudstack.py

函数create()包含以下代码

kwargs = {
    'name': vm_['name'],'image': get_image(conn,vm_),'size': get_size(conn,'location': get_location(conn,}

函数get_image和get_size传递给函数’namespaced_function’,如下所示:

get_size = namespaced_function(get_size,globals())
get_image = namespaced_function(get_image,globals())

salt.utils.functools.py

具有命名空间功能

def namespaced_function(function,global_dict,defaults=None,preserve_context=False):
    '''
    redefine (clone) a function under a different globals() namespace scope
        preserve_context:
            Allow keeping the context taken from orignal namespace,and extend it with globals() taken from
            new targetted namespace.
    '''
    if defaults is None:
        defaults = function.__defaults__

    if preserve_context:
        _global_dict = function.__globals__.copy()
        _global_dict.update(global_dict)
        global_dict = _global_dict
    new_namespaced_function = types.FunctionType(
        function.__code__,name=function.__name__,argdefs=defaults,closure=function.__closure__
    )
    new_namespaced_function.__dict__.update(function.__dict__)
    return new_namespaced_function

我可以看到他们正在动态创建一个函数get_image,但我不明白这样做的好处.为什么不创建这个功能呢?

所以问题就变成了,“namespaced_function()如何修改输入函数?”.如果您查看了什么类型.FunctionType()作为其参数,您会看到大多数值直接从原始函数复制.唯一没有直接复制的参数是函数全局变量.换句话说,namespaced_function()正在创建一个函数,它在输入函数的每个方面都是相同的,除了当函数引用全局变量时,它在不同的地方查找它们.

因此,他们正在创建一个新版本的get_image(),它也可以访问当前模块的全局变量.他们为什么这样做?好吧,要么覆盖一些全局变量,要么提供原始模块中根本不存在的变量(在这种情况下,原始函数修改之前会被故意破坏).但我真的不能回答“为什么?”除了简单地说他们可能认为它比替代品更容易.

那有什么选择呢?嗯,全局变量往往不受欢迎 – 当它们不是常数时 – 因为,你可能想要改变它们.他们本可以使用额外的参数而不是全局变量,但是当他们的大多数函数使用它们时,他们可能不希望继续传递相同的参数.你也可以注入参数,就像它们注入全局变量一样 – 而且它也不那么hacky!那他们为什么不这样做呢?好吧,再次,我有点猜测,但他们可能有不止一个全局变量,他们正在改变/提供.

自动提供参数很容易:

def original(auto1,arg1,arg2,auto2):
    print(auto1,auto2,arg2)

injected = functools.partial(original,'auto1',auto2='auto2')

injected(1,2) # is equal to original('auto1',1,2,'auto2')

自动提供大量参数会很快变得乏味.

当然,您可能只是让所有函数都有一个名为eg的参数. globals作为第一个参数,并使用inject = functools.partial(original,globals()).但是在函数内部,每当你需要引用这样一个变量时,你需要说全局变量[‘变量’]而不仅仅是变量.

所以,总的来说,它可能有点hacky,但作者可能认为“有点hacky”仍然比更冗长的替代方案好很多.

总结

以上是编程之家为你收集整理的Python的types.FunctionType如何创建动态函数?全部内容,希望文章能够帮你解决Python的types.FunctionType如何创建动态函数?所遇到的程序开发问题。


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶