dnspython 和 python 对象
我正在尝试使用 dnspython 库,并且对他们在此页面上查询 MX 记录的示例感到有点困惑: www.dnspython.org/examples.html:
import dns.resolver
answers = dns.resolver.query('dnspython.org', 'MX')
for rdata in answers:
print 'Host', rdata.exchange, 'has preference', rdata.preference
在 python CLI 中, 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']
两个事情让我感到困惑(相关):
I'm trying to use the dnspython library, and am a little confused by their example for querying MX records on this page: www.dnspython.org/examples.html:
import dns.resolver
answers = dns.resolver.query('dnspython.org', 'MX')
for rdata in answers:
print 'Host', rdata.exchange, 'has preference', rdata.preference
In the python CLI, a dir(answers) gives me:
['__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']
Two things are confusing to me (which are related):
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
到目前为止,我还没有查看过 dns.resolver - 我只是将其添加到了不断增长的待检查列表中。 我猜想
rdata
指的是资源记录类型特定数据,如 RFC1035 第 4.1.3 节。 DNS 请求的响应除了查询和标头之外还包含三个数据部分:从表面上看,
dns.resolver.query()
返回第一部分。 在这种情况下,答案部分中的每个资源记录将根据记录类型具有不同的属性。 在本例中,您请求MX
记录,因此这些记录应该具有您所拥有的完全相同的属性 -exchange
和preference
。 这些在 RFC1035 第 3.3.9 节中进行了描述。我怀疑 dns.resolver 正在覆盖 __getattr__ 或类似的东西来执行您所看到的魔法,因此您不会直接在 dir( )。 您很可能可以安全地使用 RFC1035 中定义的属性。 我明天肯定要检查一下,因为我需要一个像样的 Python DNS 子系统。
感谢您提及此模块并享受 DNS 带来的乐趣。 如果你真正深入研究它的工作原理,这确实是非常有趣的东西。 我仍然认为这是当今风靡一时的“宁静”事物的早期表达方式之一;)
I haven't looked at
dns.resolver
as of yet - I just added it to the ever-growing list of things to check out. I would guess thatrdata
refers to the resource record type specific data as described in Section 4.1.3 of RFC1035. The response of a DNS request contains three data sections in addition to the query and headers:From the looks of it
dns.resolver.query()
is returning the first section. In this case, each resource record in the answer section is going to have different attributes based on the record type. In this case, you asked forMX
records so the records should have exactly the attributes that you have -exchange
andpreference
. These are described in Section 3.3.9 of RFC1035.I suspect that
dns.resolver
is overriding__getattr__
or something similar to perform the magic that you are seeing so you won't see the fields directly in adir()
. Chances are that you are safe using the attributes as defined in RFC1035. I will definitely have to check this out tomorrow since I have need of a decent DNS subsystem for Python.Thanks for mentioning this module and have fun with DNS. It is really pretty interesting stuff if you really dig into how it works. I still think that it is one of the earlier expressions of that ReSTful thing that is all the rage these days ;)
在示例代码中,
answers
是一个包含零个或多个项目的可迭代对象,每个项目依次分配给rdata
。 要查看各个响应的属性,请尝试:In the example code,
answers
is an iterable object containing zero or more items, which are each assigned tordata
in turn. To see the properties of the individual responses, try:答案是一个可迭代的,如其“__iter__”方法所示。 将答案视为 rdata 列表。
您可以尝试这样做以从答案中获取 1 rdata:
answers is an iterable as indicated by its "__iter__" method. Think of answers as a list of rdatas.
You can try doing this to get 1 rdata from answers:
如果您使用的是 Python 2.6,则获取任何可迭代对象的第一项(例如此处的
answers
)的“正确”方法是next(iter(answers))
; 如果您想在answers
为空迭代时避免异常,则next(iter(answers), somevalue)
将返回somevalue
而不是引发StopIteration
。 如果您使用的是 2.5,则使用iter(answers).next()
,但如果需要,您必须在try/ except StopIteration:
语句中使用它处理可能的空迭代。If you're on Python 2.6, the "proper" way to get the first item of any iterable (such as
answers
here) isnext(iter(answers))
; if you want to avoid an exception whenanswers
is an empty iterable, thennext(iter(answers), somevalue)
will returnsomevalue
instead of raisingStopIteration
. If you're on 2.5, theniter(answers).next()
, but you'll have to use it inside atry/except StopIteration:
statement if you need to deal with a possible empty iterable.