【问题标题】:How can i get python function object from a string [duplicate]我如何从字符串中获取python函数对象[重复]
【发布时间】:2019-09-05 11:23:47
【问题描述】:

我有字符串格式的 python 函数,我想在程序范围内获取这些函数的 python 对象。我尝试过exec()eval()ast.literal_eval(),但这些都没有返回函数对象。

例如:

s = "def add(args):\n    try:\n        return sum([int(x) for x in args])\n    except Exception as e:\n        return 'error'\n

这是一个简单的字符串函数,用于添加列表元素。我正在寻找一个实用模块,它可以返回函数add的对象

function_obj = some_function(s)
print 'type:', type(function_obj)
type: <type 'function'>

【问题讨论】:

  • 为什么你有字符串格式的函数定义?

标签: python python-2.7


【解决方案1】:

首先将函数(作为字符串)编译成代码对象,即,

code_obj = compile(s, '<string>', 'exec')

然后使用types.FunctionType从代码对象创建新的函数类型。

>>> import types
>>> new_func_type = types.FunctionType(code_obj.co_consts[0], globals())
>>> print(type(new_func_type))
<class 'function'>
>>> new_func_type([*range(10)])
45

【讨论】:

    【解决方案2】:

    一种方法(可能有更好的方法)是:

    >>> s = "def add(args):\n    try:\n        return sum([int(x) for x in args])\n    except Exception as e:\n        return 'error'"
    >>>
    >>> def create_func_obj(func_code_str):
    ...     g = dict()
    ...     l = dict()
    ...     exec(func_code_str, g, l)
    ...     if l:
    ...         return list(l.values())[0]
    ...
    >>>
    >>> func = create_func_obj(s)
    >>>
    >>> func
    <function add at 0x000002952F0DEC80>
    >>> func([1, 2, 3])
    6
    >>>
    >>> add  # The function wasn't added in the global namespace (as an exec sideeffect)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'add' is not defined
    

    如果代码字符串中包含one函数定义之外的其他内容,则结果不会是预期的。

    【讨论】:

      【解决方案3】:

      在 Python 2 中,你可以给 exec 一个全局字典:

      globalsdict = {}
      exec s in globalsdict
      

      然后 globalsdict['add'] 将成为您的函数对象。 Globalsdict 还将包含所有内置函数。

      【讨论】:

        【解决方案4】:
        a = \
        '''def fun():\n
            print 'result'
        '''
        exec(a)
        
        fun()
        

        【讨论】:

        • 您应该添加一些解释和指向exec 文档的链接 - 否则人们会建议您删除您的答案。
        猜你喜欢
        • 2021-05-24
        • 2019-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 2022-08-14
        相关资源
        最近更新 更多