简体   繁体   中英

Duck typing and foreign objects

I'm currently replicating something similar to this question: python switch by class name?

I have a for loop that iterates over a set of objects and sorts them, by their type, into one of several lists.

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

etc. for several other classes. The application is something like an ORM - data from each class will be extracted and written to a database, and each class has different data to extract. Additionally, it is necessary that all instances of Class1 be processed by the ORM before any instances of Class2.

Lastly, Class1 and Class2 are not mine - they're the output of an API that I'm using, so I have no ability to change them as is suggested in the previous question (like, writing a serialize() method that dumps the data I need in each class). I make a request to the API for some objects, and it floods me with objects of various types, from each of which I need to extract different data.

Is there a more pythonic way of doing this? This approach meets the need, but it hurts my eyes and I'd like to learn a better way. I'm pretty new to Python still.

Another approach, depending on your specifics, might make use of the fact that the type type is immutable, and thus able to be used as a dictionary key.

So you could do something like:

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)

Output:

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

The idea here is that you don't need to write a whole bunch of if isinstance tests, you just "group by" each object's type.

You can access values of the dictionary by using the class name as the key:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM