fetchmailconf конфигурацию как значение переменой 'fetchmail'.

Однако описанное препятствие было не последним. Было действительно необходимо не только предоставить fetchmail существующую конфигурацию, но превратить ее в связанное дерево действующих объектов. В данном дереве было бы 3 вида объектов: Configuration (объект верхнего уровня, представляющий всю конфигурацию), Site (представляющий один из серверов для опроса) и User (представляющий пользовательские данные, связанные с узлом). Файл в примере описывает 3 объекта Site, каждый из которых связан с одним пользовательским объектом.

Данные 3 класса объектов уже существовали в fetchmailconf. Каждый из них имел метод, который заставлял его выводить на экран GUI-панель редактирования для модификации своего экземпляра данных. Последняя проблема сводилась к некоторому преобразованию статических данных в Python-инициализаторе в действующие объекты.

Пример 9.2. Дамп Python-структуры для конфигурации fetchmail

fetchmailrc = {

 'poll_interval':300,

 'logfile':None,

 'postmaster':'esr',

 'bouncemail':TRUE,

 'properties':None,

 'invisible':FALSE,

 'syslog' :FALSE,

 # List of server entries begins here

 # (Ниже начинается список серверов)

 'servers': [

   # Entry for site `imap.ccil.org' begins:

   # (Начало записи для узла imap.ccil.org:)

   {

    'pollname':'imap.ccil.org',

    'active':TRUE,

    'via':None,

    'protocol':'IMAP',

    'port':0,

    'timeout':300,

    'dns':FALSE,

    'aka':['snark.thyrsus.com','locke.ccil.org','ccil.org'],

    'users': [

     {

      'remote':'esr',

      'password':'masked_one',

      'localnames':['esr'],

      'fetchall':TRUE,

      'keep':FALSE,

      'flush':FALSE,

      'mda':None,

      'limit':0,

      'warnings':3600,

     }

    ' ]

   }

  '

  # Entry for site `imap.netaxs.com' begins:

  # (Начало записи для узла imap.netaxs.com:)

  {

   'pollname':'imap.netaxs.com',

   'active':TRUE,

   'via':None,

   'protocol':'IMAP',

   'port':0,

   'timeout':300,

   'dns':TRUE,

   'aka':None,

   'users': [

    {

     'remote':'esr',

     'password':'masked_two',

     'localnames':['esr'],

     'fetchall':FALSE,

     'keep':FALSE,

     'flush':FALSE,

     'mda':None,

     'limit':0,

     'warnings':3600,

    }

   ' ]

  }

  '

 ]

}

Рассматривалась идея написания связующего уровня, который имел бы явную информацию о структуре всех 3 классов и использовал бы данную информацию для просмотра инициализатора при создании соответствующих объектов. Однако данная идея была отклонена, поскольку существовала вероятность добавления со временем новых членов класса, по мере создания новых функций в конфигурационном языке. Если бы код создания объектов был написан таким очевидным путем, то он также был бы хрупким и склонным к рассинхронизации при изменении определения классов либо структуры инициализатора, выводимой с помощью генератора отчетов --configdump. Подобный подход приводит к бесконечному появлению ошибок.

Более надежным способом было бы использование создание программы, управляемой данными, т.е. кода, который анализировал бы форму и члены инициализатора, опрашивал бы определения классов об их членах, а затем согласовывал бы оба набора.

Программисты, работающие с Lisp и Java, называют данную методику интроспекцией (introspection). В некоторых других объектно-ориентированных языках она называется программированием метаклассов (metaclass hacking) и, как правило, считается 'черной магией', понятной только 'посвященным'. В большинстве объектно- ориентированных языков данная методика не поддерживается вообще, а в тех языках, где она поддерживается (среди них Perl и Java), она часто сложна и ненадежна. Однако в языке Python средства интроспекции и программирования метаклассов исключительно доступны.

В примере 9.3 приведен фрагмент кода приблизительно со строки 1895 в версии 1.43.

Пример 9.3. Код метакласса copy_instance

def copy_instance(toclass, fromdict):

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату