在运行时创建一个 python 函数来匹配可变数量的字典条目

发布于 2024-09-15 23:37:14 字数 1434 浏览 4 评论 0原文

我正在编写一个程序来计算 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']]

其中每个子列表的第一个元素是字段编号,第二个元素是值)

我尝试迭代此规则列表以累积 lambda 表达式:

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

Lambda 是后期绑定的?那么这适用于表达式中的所有标识符还是仅适用于作为参数传入的标识符?看来前者是正确的

实现此功能的最佳方法是什么?我觉得我目前的处理方式是错误的。也许这是 lambda 表达式的错误使用,但我不知道更好的替代方案。

I'm making a program to calculate latency from a tcpdump/pcap file and I want to be able to specify rules on the command line to correlate packets -- i.e. find the time taken between sending a packet matching rule A to receiving a packet matching rule B (concrete example would be a FIX NewOrderSingle being sent and a corresponding FIX ExecutionReport being received).

This is an example of the fields in the packet (before they've been converted into dictionary form) -- I'm testing the numerical version of the field (in parentheses) rather than the English version:

    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]

Currently I have the arguments coming off the command line into a nested list:

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

(where the first element of each sublist is the field number and second is the value)

I've tried iterating over this list of rules to accumulate a lambda expression:

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)

When I run the program though, I get the output:

RuntimeError: maximum recursion depth exceeded in cmp

Lambdas are late-binding? So does this apply to all identifiers in the expression or just those passed in as arguments? It seems the former is true

What's the best way to achieve this functionality? I feel like I'm going about this the wrong way currently. Maybe this is a bad use of lambda expressions, but I don't know a better alternative for this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆夏时光 2024-09-22 23:37:14

不要使用 lambda。它们是后期绑定。也许您想要来自 functoolspartial,但即使这样似乎也太复杂了。

您传入的数据包含字段名称、数字和值,对吧?

您的命令行参数使用字段编号和值,对吗?

您需要一个以字段编号作为键的字典。在这种情况下,您不需要任何复杂的查找。你只是想要这样的东西。

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

像这样的东西应该可以为你处理一切。

Don't use lambdas. They are late binding. Perhaps you want a partial from functools, but even that seems too complex.

Your data coming in has field names, numbers and values, right?

Your command-line parameters use field numbers and values, right?

You want a dictionary keyed by field number. In that case, you don't need any complex lookups. You just want something like this.

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

Something like that should handle everything for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文