Создайте функцию python во время выполнения, чтобы соответствовать переменному количеству словарных статей

1

Я делаю программу для вычисления задержки из файла tcpdump/pcap, и я хочу иметь возможность указывать правила в командной строке для корреляции пакетов - то есть найти время, затраченное на отправку правила сопоставления пакетов A на прием правило B сопоставления пакетов (конкретный пример будет отправлен FIX NewOrderSingle и будет получен соответствующий FIX ExecutionReport).

Это пример полей в пакете (до того, как они были преобразованы в форму словаря). Я тестирую числовую версию поля (в скобках), а не английскую версию:

    BeginString (8): FIX.4.2
    BodyLength (9): 132
    MsgType (35): D (ORDER SINGLE)
    SenderCompID (49): XXXX
    TargetCompID (56): EXCHANGE
    MsgSeqNum (34): 1409104
    SendingTime (52): 20100723-12:49:52.296
    Side (54): 1 (BUY)
    Symbol (55): A002
    ClOrdID (11): BUY704552
    OrderQty (38): 1000
    OrdType (40): 2 (LIMIT)
    Price (44): 130002
    TimeInForce (59): 3 (IMMEDIATE OR CANCEL)
    QuoteID (117): A002
    RelatdSym (46): A002
    CheckSum (10): 219 [correct]

В настоящее время у меня есть аргументы, выходящие из командной строки во вложенный список:

[[35, 'D'], [55, 'A002']]

(где первый элемент каждого подсписка - это номер поля, а второй - значение)

Я пробовал перебирать этот список правил для накопления выражения лямбда:

for field, value in args.send["fields_filter"]:
    if matchers["send"] == None:
        matchers["send"] = lambda fix : field in fix and fix[field] == value
    else:
        matchers["send"] = lambda fix : field in fix and fix[field] == value and matchers["send"](fix)

Когда я запускаю программу, я получаю вывод:

RuntimeError: maximum recursion depth exceeded in cmp

Lambdas являются поздними связями? Значит ли это применимо ко всем идентификаторам в выражении или только к тем, которые были переданы в качестве аргументов? Кажется, что первое верно.

Какой лучший способ достичь этой функциональности? Я чувствую, что в настоящее время я ошибаюсь. Может быть, это плохое использование лямбда-выражений, но я не знаю лучшей альтернативы для этого.

  • 0
    Я не совсем уверен, что ваш код пытается выполнить ... но последняя строка выглядит как классическая рекурсивная функция. Вы назначаете лямбда-функцию клавише 'send' в запросе matchers, чтобы mathers ['send'] (fix) был рекурсивным вызовом. Там нет завершающего условия, поэтому он просто работает, пока не взорвет стек. Я не могу говорить о том, является ли лямбда-дизайн «хорошим» или нет, но эта конкретная проблема выглядит просто как типичная ошибка реализации.
  • 0
    @Rakis: Так что я пытался скомпилировать что-то вроде: <code> 35 в исправлении и исправлении [35] == «D» и (55 в исправлении и исправлении [55] == «A002») ) </ code> Условия в нем будут зависеть от того, что входит в командную строку. Посмотрите ответ С. Лотта, так как он подводит итог того, что я хочу.
Теги:
dynamic
lambda
matching

1 ответ

2
Лучший ответ

Не используйте лямбды. Они являются поздними связями. Возможно, вам нужен partial от functools, но даже это кажется слишком сложным.

Входящие данные имеют имена полей, цифры и значения, верно?

В параметрах командной строки используются номера и значения полей, правильно?

Вам нужен словарь с номером поля. В этом случае вам не нужны сложные поисковые запросы. Вам просто нужно что-то подобное.

def match( packet_dict, criteria_list ):
    t = [ packet_dict[f] == v for f,v in criteria_list ]
    return any( t )

Что-то вроде этого должно обрабатывать все для вас.

  • 0
    Спасибо за предложение частичного, я смотрю на это. Я пытался избежать выполнения итерации каждый раз, когда выполняю это для дампов миллионов пакетов, и подумал, что с самого начала генерируется какая-то функция сопоставления и что каждый раз вызывается гораздо эффективнее. Я попробую и посмотрю, насколько хорошо он работает.
  • 0
    @davedavedave: частичное не очень поможет. Словарь хеширует поиск мгновенно. Цикл критериев небольшой с удивительно небольшими накладными расходами.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню