dnspython和Python对象

2 投票
4 回答
6487 浏览
提问于 2025-04-15 11:42

我正在尝试使用dnspython这个库,但对他们在这个页面:www.dnspython.org/examples.html上提供的查询MX记录的例子有点困惑:

import dns.resolver

answers = dns.resolver.query('dnspython.org', 'MX')
for rdata in answers:
    print 'Host', rdata.exchange, 'has preference', rdata.preference

在Python的命令行界面中,输入dir(answers)会给我返回:

['__class__', '__delattr__', '__delitem__', '__delslice__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'expiration', 'qname', 'rdclass', 'rdtype', 'response', 'rrset']

有两件事让我感到困惑(这两者是相关的):

  • 对answers对象进行迭代时,例子中的rdata是什么?
  • answers的属性或方法中没有一个叫exchange或preference。显然,rdata并不是answers的简单别名,但我不明白这些属性是从哪里来的。
  • 4 个回答

    1

    在这个示例代码中,answers 是一个可遍历的对象,它里面可以有零个或多个项目。每一个项目都会依次被赋值给 rdata。如果你想查看每个响应的属性,可以试试:

    dir(answers[0])
    
    1

    “answers”是一个可遍历的对象,这意味着它有一个叫做“__iter__”的方法。你可以把“answers”想象成一个包含多个“rdatas”的列表。

    你可以试着这样做,从“answers”中获取一个“rdata”:

    answers.__iter__().next()
    
    1

    我还没看过 dns.resolver,只是把它加到了我越来越长的待研究列表里。我猜 rdata 是指资源记录类型特定的数据,具体可以参考RFC1035的第4.1.3节。DNS请求的响应除了查询和头部信息外,还包含三个数据部分:

    1. 答案
    2. 权威名称服务器记录
    3. 附加资源记录

    看起来 dns.resolver.query() 返回的是第一部分。在这种情况下,答案部分的每个资源记录会根据记录类型有不同的属性。你请求的是 MX 记录,所以这些记录应该正好有你所需要的属性——exchangepreference。这些在RFC1035的第3.3.9节中有描述。

    我怀疑 dns.resolver 可能重写了 __getattr__ 或类似的东西,来实现你看到的那些效果,所以你在使用 dir() 时可能看不到这些字段。大概率上,你可以安全地使用RFC1035中定义的属性。明天我一定要好好研究一下,因为我需要一个不错的DNS子系统来用在Python里。

    谢谢你提到这个模块,玩得开心哦!如果你深入了解它的工作原理,会发现这真的很有趣。我仍然认为这是当今流行的ReSTful概念的早期表现之一;)

    撰写回答