使用functools.singledispatch装饰器简化复杂的类型判断

我之前写过一个使用生成器的列表铺平函数。

from collections.abc import Iterable
def flatten(source):
    if isinstance(source, Iterable) and not isinstance(source, str):
        for element in source:
            yield from flatten(element)
    else:
        yield source

可以获得较好的执行结果。

这个方案已经算是很简洁了,但还是用了if语句进行类型判断。现在我们借用functools.singledispatch()函数装饰器和类型注解,可以将上面的逻辑按照参数的类型分解到三个函数里,从而消除if语句的使用。

from functools import singledispatch
from collections.abc import Iterable

@singledispatch
def flatten_generic(source):
    pass

@flatten_generic.register
def _(source: object):
    yield source

@flatten_generic.register
def _(source: str):
    yield source

@flatten_generic.register
def _(source: Iterable):
    for x in source:
        yield from flatten_generic(x)

这样我们就减少了if语句的使用,这在更复杂的类型判断中作用更加明显,例如实现一个通用的序列化函数。

值得注意的是通过函数注解使用functools.singledispatch()只在Python3.7版本才可以,之前的版本要显式的将类型参数传入@flatten.generic.register(type)装饰器里。

@flatten_generic.register(str)
def _(source):
    yield source

虽然类型注解在Python中广受争议,但在这个情景里还是非常有用的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏个人随笔

深入理解Java异常处理机制 (笼统篇)

801
来自专栏Linyb极客之路

JVM 方法内联

调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。

1824
来自专栏Coco的专栏

【优雅代码】深入浅出 妙用Javascript中apply、call、bind

842
来自专栏测试开发架构之路

C++之类和对象的特性

简介:C++并不是一个纯粹的面向对象的语言,而是一种基于过程和面向对象的混合型的语言。 凡是以类对象为基本构成单位的程序称为基于对象的程序,再加上抽象、封装、...

3406
来自专栏java技术学习之道

Java异常详解及如何处理

2165
来自专栏一“技”之长

Swift专题讲解二十二——泛型 原

        泛型是Swift语言强大的核心,泛型是对类型的抽象,使用泛型开发者可以更加灵活方便的表达代码意图。我们知道,有参函数的参数必须有一个明确的参数类...

551
来自专栏编程

Java中正则表达式分类及使用方法,分门别类,总结的很好

1、正则表达式是什么? 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。 作用 : 比如注册邮箱 , 邮...

1885
来自专栏鸿的学习笔记

python稍难一点的说明

682
来自专栏Java帮帮-微信公众号-技术文章全总结

【选择题】Java基础测试四(15道)

【选择题】Java基础测试四(15道) 41.以下哪项是接口的正确定义?( B D ) A、 interface B { void print...

4819
来自专栏简书专栏

Python闭包函数和装饰器

1.概念:在一个外函数中定义了一个内函数,内函数运用了外函数的临时变量,并且外函数的返回值是内函数的引用 示例代码:演示函数嵌套和闭包。

1134

扫码关注云+社区

领取腾讯云代金券