Сопоставление на основе различных типов и атрибутов объекта - PullRequest
0 голосов
/ 26 мая 2019

У меня есть список объектов, из которых я пытаюсь фильтровать объекты на основе выбранных критериев, возвращая список совпадений.Атрибутами являются строки, целые числа, числа с плавающей запятой и объекты.У меня проблема при попытке фильтрации по атрибутам объекта, я хотел бы сделать это:

findOrder (d, signal = 'CO', contract.symbol = 1)

Я не могу просто сравнивать объекты сами по себе, поскольку мне нужно только сопоставить на основе самых важных атрибутов, а атрибуты различаются для разных объектов.

До сих пор я могу успешно сгладить объекты в диктовкуа затем сделать простое сравнение словаря.Все же это очень уродливо, и я подозреваю, что медленно:

findOrder (d, signal = 'CO', contractSymbol = 1)

class emptyObj(object):
    def __init__(self, a, b):
        self.Symbol = a
        self.Order = b
s = emptyObj(a=1, b=2)

class toObj(object):
    def __init__(self, d): [setattr(self, a, b) for a, b in d.items()]

def findOrder(d, **kwargs):
    def flatten(di):
        ls = []
        for o in di:
            e = {}
            for k, v in o.__dict__.items():
                if isinstance(v, (int, float, str, tuple, list, dict)):
                    e[k] = v
                else:
                    for attr, val in v.__dict__.items(): e[str(k)+str(attr)] = val
            ls.append(e)
        return ls

    g = flatten(d)
    l = [k for k in g if kwargs.items() <= k.items()]
    if l: return l

d = [toObj({'id':1250, 'signal': 'CO', 'contract': s}),
     toObj({'id':1252, 'signal': 'LO', 'contract': s})]

print(findOrder(d, signal='CO'))

Есть ли более оптимальныйи простой способ сделать это?

1 Ответ

0 голосов
/ 26 мая 2019

Если вы пытаетесь отфильтровать объекты по атрибуту, используйте либо filter, либо список с функцией, проверяющей атрибуты:

def check_attrs(**kw):
    def wrapper(obj):
        return all(getattr(obj, k) == v for k, v in kw.items())
    return wrapper

Затем вы фильтруете объекты:

filtered = list(filter(check_attrs(signal='CO'), objects))

Или ...

filtered = [obj for obj in objects
            if check_attrs(signal='CO')(obj)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...