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'] 

Две вещи сбивают меня с толку (которые связаны):

  • Итерация по объекту ответов. Что такое rdata в примере?
  • Ни один из атрибутов или методов ответов не соответствует обмену или предпочтению. Очевидно, что rdata - это не просто псевдоним ответов, но я не понимаю, откуда берутся эти атрибуты.
  • 4 ответа

    Решение

    Я не смотрел на dns.resolver на данный момент - я просто добавил его в постоянно растущий список вещей, чтобы проверить. Я бы догадался, что rdata относится к конкретным данным типа записи ресурса, как описано в разделе 4.1.3 RFC1035. Ответ на запрос DNS содержит три раздела данных в дополнение к запросу и заголовкам:

    1. ответы
    2. Официальные записи сервера имен
    3. Дополнительные записи ресурса

    Судя по всему 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: заявление, если вам нужно иметь дело с возможной пустой итерацией.

    Другие вопросы по тегам