【问题标题】:Duck typing and foreign objects鸭子打字和异物
【发布时间】:2016-08-02 07:01:28
【问题描述】:

我目前正在复制与此问题类似的内容:python switch by class name?

我有一个 for 循环,它遍历一组对象并按它们的类型将它们排序到几个列表中的一个中。

for obj in list_of_things:
    if isinstance(obj, Class1):
        class1list.append(obj)
    if isinstance(obj, Class2):
        class2list.append(obj)

等等。对于其他几个课程。该应用程序类似于 ORM - 每个类的数据将被提取并写入数据库,每个类都有不同的数据要提取。此外,所有 Class1 的实例都必须在 Class2 的任何实例之前由 ORM 处理。

最后,Class1 和 Class2 不是我的 - 它们是我正在使用的 API 的输出,因此我无法按照上一个问题中的建议更改它们(例如,编写 serialize() 方法转储我在每个类中需要的数据)。我向 API 发出一些对象的请求,它向我涌来各种类型的对象,我需要从每个对象中提取不同的数据。

有没有更 Pythonic 的方式来做到这一点?这种方法满足了需求,但它伤害了我的眼睛,我想学习一个更好的方法。我对 Python 还是很陌生。

【问题讨论】:

    标签: python serialization duck-typing


    【解决方案1】:

    根据您的具体情况,另一种方法可能会利用 type 类型是不可变的这一事实,因此可以用作字典键。

    所以你可以这样做:

    from collections import defaultdict
    
    list_of_things = [2, 3, "Some", "String"]
    
    obj_map = defaultdict(list)    
    for obj in list_of_things:
        obj_map[type(obj)].append(obj)
    
    print(obj_map)
    

    输出:

    defaultdict(<type 'list'>, {
        <type 'int'>: [2, 3], 
        <type 'str'>: ['Some', 'String']
    })
    

    这里的想法是您不需要编写一大堆if isinstance 测试,您只需“按”每个对象的类型进行“分组”。

    您可以通过使用类名作为键来访问字典的值:

    print(obj_map[int])    # [2, 3]
    

    【讨论】:

    • 我想过这个,但我的理解是 type() 不尊重子类关系,所以如果第 3 方 API 子类 Class1 但我想将子类视为 Class1 的实例,它会不能够。现在,我碰巧知道我不会得到任何子类,但我认为使用 type() 与 isinstance() 可以想象这样改变结果是否正确?
    • @JustinPalpant 你是对的,子类添加到不同的键下。您可以对type(obj).__bases__ 进行一些反省,但我只看到它变得越来越丑陋。但是,如果在不同的键下添加子类实例是可以接受的,您总是可以使用issubclass() 拉出给定类及其子类的实例
    • 我不知道issubclass(),听起来它可以填补最后一个细分市场。我同意type(obj).__bases__ 似乎会变得一团糟。我将把它标记为已接受。
    猜你喜欢
    • 2011-11-25
    • 2013-03-02
    • 1970-01-01
    • 2011-09-28
    • 2012-10-26
    • 2011-03-23
    • 2011-05-11
    • 2020-02-13
    • 2011-10-27
    相关资源
    最近更新 更多