dnspython и python объекты - PullRequest
2 голосов
/ 20 мая 2009

Я пытаюсь использовать библиотеку 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__', '__hash__', '__init__', '__iter__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'expiration', 'qname', 'rdclass', 'rdtype', 'response', 'rrset']

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

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

Ответы [ 4 ]

1 голос
/ 20 мая 2009

Я еще не смотрел на 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, которое сейчас в моде;)

1 голос
/ 20 мая 2009

ответов является итеративным, как указано его методом "__iter__". Думайте об ответах как о списке rdatas.

Вы можете попробовать сделать это, чтобы получить 1 rdata из ответов:

answers.__iter__().next()
1 голос
/ 20 мая 2009

В примере кода answers - это итеративный объект, содержащий ноль или более элементов, каждый из которых назначается rdata по очереди. Чтобы увидеть свойства отдельных ответов, попробуйте:

dir(answers[0])
0 голосов
/ 20 мая 2009

Если вы используете Python 2.6, «правильный» способ получить первый элемент любого итерируемого (например, answers здесь) - next(iter(answers)); если вы хотите избежать исключения, когда answers является пустой итерируемой, тогда next(iter(answers), somevalue) вернет somevalue вместо повышения StopIteration. Если вы используете 2.5, тогда iter(answers).next(), но вам придется использовать его внутри оператора try/except StopIteration:, если вам нужно иметь дело с возможной пустой итерацией.

...