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
В CLI Python DIR (ответы) дает мне:
['__class__', '__delattr__', '__delitem__', '__delslice__', '__dict__', '__doc__', '__getattr__', '__getattribute__', '__getitem__', '__getslice__' '' ___, ___ ___, ___ ___, ___ ___ ___, ___ ___, ___ ___, ___ ___ ___ ___, ___ ___ ___ ___ __iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'expiration', 'qc ',, 'rdtype', 'response', 'rrset']
Две вещи сбивают меня с толку (которые связаны):
4 ответа
Я не смотрел на dns.resolver
на данный момент - я просто добавил его в постоянно растущий список вещей, чтобы проверить. Я бы догадался, что rdata
относится к конкретным данным типа записи ресурса, как описано в разделе 4.1.3 RFC1035. Ответ на запрос DNS содержит три раздела данных в дополнение к запросу и заголовкам:
- ответы
- Официальные записи сервера имен
- Дополнительные записи ресурса
Судя по всему dns.resolver.query()
возвращает первый раздел. В этом случае каждая запись ресурса в разделе ответов будет иметь разные атрибуты в зависимости от типа записи. В этом случае вы просили MX
записи, поэтому записи должны иметь именно те атрибуты, которые у вас есть - exchange
а также preference
, Они описаны в разделе 3.3.9 RFC1035.
Я подозреваю что dns.resolver
имеет приоритет __getattr__
или что-то подобное, чтобы выполнить магию, которую вы видите, так что вы не увидите поля непосредственно в dir()
, Скорее всего, вы в безопасности, используя атрибуты, определенные в RFC1035. Я определенно должен буду проверить это завтра, так как мне нужна достойная подсистема DNS для Python.
Спасибо за упоминание этого модуля и получайте удовольствие от DNS. Это действительно довольно интересный материал, если вы действительно вникаете в его работу. Я до сих пор думаю, что это одно из более ранних выражений этой ReSTful, которое сейчас в моде;)
Ответы являются итеративными, как указано их методом "__iter__". Думайте об ответах как о списке rdatas.
Вы можете попробовать сделать это, чтобы получить 1 rdata из ответов:
answers.__iter__().next()
В примере кода answers
итеративный объект, содержащий ноль или более элементов, каждый из которых назначен rdata
в очереди. Чтобы увидеть свойства отдельных ответов, попробуйте:
dir(answers[0])
Если вы на Python 2.6, "правильный" способ получить первый элемент любого итерируемого (например, answers
здесь) next(iter(answers))
; если вы хотите избежать исключения, когда answers
является пустой итерацией, то next(iter(answers), somevalue)
вернусь somevalue
вместо того, чтобы поднимать StopIteration
, Если вы на 2.5, то iter(answers).next()
, но вам придется использовать его внутри try/except StopIteration:
заявление, если вам нужно иметь дело с возможной пустой итерацией.