关于python:function_exists在python3中存在吗

function_exists in PHP for python3

本问题已经有最佳答案,请猛点这里访问。

python3的php中是否有类似于function_exists的东西?我正在实现一些允许用户(通过一些Web UI)在JSON中定义简单规则的功能,如下所示(在一些奇怪的类似Lisp的结构中):

1
["_and", ["_tautology"], ["tautology"]]

并希望将其转换为python语句,例如这些函数

1
2
3
4
5
6
7
8
import operator
from functools import reduce

def _and(*args):
    return lambda context: reduce(operator.and, [arg(context) for arg in args], True)

def _tautology(*_):
    return lambda *__: True

把原来的JSON规则转换成

1
_and(_tautology(), _tautology())

只是出于好奇,ast是为这类任务而设计的吗?我以前做过一次,但我在寻找可扩展的东西。因为我在这之前所做的实际上是维护如下的字典

1
mapping = {'_and': _and}

列表将不断增长,这将导致更多的代码类型化来描述字符串值的含义,而不是实现它们。或者我应该使用另一个规则引擎?因为其中一条规则看起来像

1
2
["_and", ["_equals","fieldA","some_value"],
         ["_equals","fieldB","some_other_value"]]

假设_equals

1
2
def _equals(field_name, value):
    return lambda context: context[field_name] == value

使规则扩展到

1
2
_and(_equals('fieldA', 'some_value'),
     _equals('fieldB', 'some_other_value'))

DR

主要问题:对于python3,是否有类似于function_exists的东西,ast适合这个?第二个问题:我应该使用某种规则引擎来代替它吗?

关于重复问题报告"否",我不检查是否存在变量。我想知道是否有一个与字符串值相同的函数。例如,如果我有一个字符串EDOCX1,5,我想知道是否有一个名为EDCOX1(6)}的函数,而不是想弄清楚这个标识符EDCOX1(6)是否实际上是一个函数。


正如莫尔顿指出的,可以使用EDCOX1 0和EDCOX1 1来使用包含名称的字符串来提取变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
In [32]: a = 1

In [33]: def b():
    c = 2
    print(globals()['a'])
    print(globals()['b'])
    print(locals()['c'])
   ....:    

In [34]: b()
1
<function b at 0x7f425cae3ae8>
2

但是!对于您的任务,我建议使用自动将函数注册到映射的装饰器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
_mapping = {}


def register(f):
    _mapping[f.__name__] = f
    return f


@register
def _and(*args):
    return lambda context: reduce(operator.and_,
                                  [arg(context) for arg in args], True)

@register
def _tautology(*_):
    return lambda *_: True

所以你的function_exists应该是

1
_mapping[key]

AST适用于检查从解析的python源代码生成的语法树,修改现有的语法树并生成新的语法树,并通过从不同的语言生成语法树(列举一些用法)传播到python。所以在某种程度上,可以从JSON生成AST并编译它。我相信这实际上是hy所做的,虽然不是来自json,而是全面的lisp语法。