微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

避免在无法使用多态的情况下使用type比较

如何解决避免在无法使用多态的情况下使用type比较

|| 我在《如何像计算机科学家一样思考》(此处)中遇到了以下内容
def recursive_sum(nested_num_list):
    sum = 0
    for element in nested_num_list:
        if type(element) == type([]):
            sum = sum + recursive_sum(element)
        else:
            sum = sum + element
    return sum
我对使用type(element)== type([])感到震惊。这不仅是不好的做法,而且此功能不适用于任何其他序列类型。多态是避免类型比较的典型方法,但是不能在此处使用。在这种情况下如何避免类型比较?我考虑过:
def recursive_sum(nested_sum_list):
    sum = 0
    for element in nested_num_list:
        try:
            sum += element
        except TypeError:
            sum += recursive_sum(element)
    return sum
这使该功能适用​​于其他序列,但仍然有些困难。谢谢!     

解决方法

\“ sum \”函数需要迭代,因此我将使用\“ hasattr \”内置函数来检查元素是否实现
__iter__
方法。 像这样:
def recursive_sum(nested_num_list):
    sum = 0
    for element in nested_num_list:
        if hasattr(element,\'__iter__\'):
            sum = sum + recursive_sum(element)
        else:
            sum = sum + element
    return sum
    ,您可以使用
isinstance(element,collections.Sequence)
检查元素是否为序列。     ,对于扁平化的嵌套列表,您将始终需要某种检查来测试元素本身是可迭代的还是叶节点。我不会在一个函数中将扁平化与计算总和结合起来,而是定义了一个只进行扁平化的生成器函数:
def flatten(x):
    try:
        it = iter(x)
    except TypeError:
        yield x
    else:
        for i in it:
            for j in flatten(i):
                yield j
这样,您将在一个函数中包含所有丑陋的位。对于嵌套序列
x
,您现在可以
sum(flatten(x))
得到递归和。     ,列表的正确内容:
>>> import collections
>>> hasattr(element,\'__getitem__\')
True
>>> not hasattr(element,\'keys\')
True
>>> isinstance(element,collections.Sequence)
True
>>> hasattr(element,\'__iter__\')
True
字符串是正确的:
>>> string = \'1234\'
>>> hasattr(string,\'__getitem__\')
True
>>> not hasattr(string,\'keys\')
True
>>> isinstance(string,collections.Sequence)
True
>>> hasattr(string,\'__iter__\')
False
    ,您在这里看到的不是我所知道的任何一种语言的多态性。清单的“ 10”代表一件事,而数字则代表另一件事。您希望“ 10”代表列表表示不寻常的东西(将所有元素加和并返回总和)-但这仅对您的特定示例有意义。对于列表的其他(我最多说)用法,uses10ѭ的原始含义要方便得多。 为了使它真正具有多态性,您可以从ѭ13派生,并使
+=
表示您想要的内容-那么您将不需要这些技巧。 顺便说一句:
if type(element) == type([]):
应该改写为:
if isinstance(element,list):
    ,此函数的目的不是普遍适用于添加嵌套结构,它只是为了说明递归而创建的。 添加更复杂的序列类型检查,try和except,或添加数字以外的内容的功能会使该函数作为递归的学习工具的作用降低。 话虽这么说,在这里ѭ17可能更合适,并且不会增加任何复杂性。     ,您正在检查是否可以将元素添加到int中,这不是您想要的。 尽管
try
还不错:尝试将其用作可迭代对象-如果它起作用,则它是可迭代对象:
def recursive_sum(nested_sum_list):
    sum = 0
    # this raises TypeError if element is not a sequence
    for element in nested_num_list: 
        try:
            sum += recursive_sum(element)
        except TypeError:
            sum += element
    return sum
还有一个可迭代的类型类:
import collections
print isinstance(element,collections.Iterable)
基本上只搜索
__iter__
方法。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。