3

我想根据传递给“调度”函数(例如 using )的参数的数据类型来调度 Python 函数(例如使用dict 方法isinstance())。是否有实施替代方案?最简单的方法是什么?

4

2 回答 2

7

从 Python 3.4 开始,Python 标准库包括对@singledispatch()泛型函数的支持。

这使您可以注册多个函数来处理不同的类型,并且它将根据类型处理分派,包括子类测试和缓存。该方法在PEP 443 - Single-dispatch generic functions中描述。

PyPI 上有一个支持 Python 2.6 及更高版本的 backport,由 PEP 作者编写。

请注意,Python 2.7 将很快达到最终的生命周期结束日期,届时它将不再接收错误修复和安全更新;您确实需要尽早计划升级到 Python 3。当您这样做时,您会注意到 Python 3.7 版本支持使用类型提示来记录每个函数接受的类型。

例如,从嵌套的字典和列表数据结构(典型的 JSON 数据结构)中删除None和值的一系列函数可以定义为:False

from functools import singledispatch

@singledispatch
def remove_null_false(ob):
    return ob

@remove_null_false.register
def _process_list(ob: list):
    return [remove_null_false(v) for v in ob]

@remove_null_false.register
def _process_list(ob: dict):
    return {k: remove_null_false(v) for k, v in ob.items()
            if v is not None and v is not True and v is not False}

在 Python 版本 < 3.7 中,您必须将类型移动到@remove_null_false.register(...)装饰器工厂符号。

于 2018-07-24T16:25:22.520 回答
2

请看下面的例子。

def get_int_square(a):
    """
    Returns square of integer parameter
    """
    return a ** 2

def get_float_cube(a):
    """
    Returns cube of float parameter
    """
    return a ** 3

def sum_of_items(l):
    """
    Returns sum of all the items in list
    """
    return sum(l)

def get_squared_items(t):
    return tuple(item ** 2 for item in t)

def dispatching(a):
    """
    Calls the corresponding functions based on match found in the dictionary
    """
    functions = {
        'int': get_int_square,
        'float': get_float_cube,
        'list': sum_of_items,
        'tuple': get_squared_items
    }

    data_type = str(type(a)).split("'")[1]
    result = functions[data_type](a)
    return result

if __name__ == "__main__":
    print(dispatching(12))  # 144
    print(dispatching(1.2)) # 1.7279999999999998
    print(dispatching((4, 7, 9, 3, 1, 5, 8))) # (16, 49, 81, 9, 1, 25, 64)
    print(dispatching([56, 4, 50, 26, 24]))   # 160
于 2018-07-24T17:02:03.677 回答