我之前写过一个使用生成器的列表铺平函数。
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中广受争议,但在这个情景里还是非常有用的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。