Двунаправленное отображение Python - PullRequest
5 голосов
/ 14 февраля 2012

Я не уверен, как назвать то, что я ищу;так что если я не смог найти этот вопрос еще где, я прошу прощения.Короче говоря, я пишу код на Python, который будет напрямую взаимодействовать с ядром Linux.Легко получить требуемые значения из файлов заголовков включения и записать их в мой источник:

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7

Эти значения легко использовать при построении структур для отправки в ядро.Тем не менее, они почти не помогают определить значения в ответах ядра.

Если я введу значения в dict, мне нужно будет просмотреть все значения в dict, чтобы найти ключи для каждого элемента в каждой структуре из ядра, которое я предполагаю.Должен быть более простой и эффективный способ.

Как бы вы это сделали?(не стесняйтесь повторить вопрос, если он уходит)

Ответы [ 3 ]

9 голосов
/ 15 февраля 2012

Если вы хотите использовать два дикта, вы можете попробовать это, чтобы создать инвертированный дикт:

b = {v: k for k, v in a.iteritems()}
2 голосов
/ 23 марта 2013

Ваше решение оставляет много работы для повторного человека, создающего файл.Это источник ошибки (вы должны написать каждое имя три раза).Если у вас есть файл, в который нужно время от времени обновлять его (например, когда выходят новые выпуски ядра), вам суждено рано или поздно включить ошибку.На самом деле, это был просто длинный способ сказать, что ваше решение нарушает DRY .

Я бы изменил ваше решение на что-то вроде этого:

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7
__IFA_MAX      =  8

values = {globals()[x]:x for x in dir() if x.startswith('IFA_') or x.startswith('__IFA_')}

Это былоvalues dict генерируется автоматически.Возможно, вы захотите (или должны) изменить условие в операторе if в соответствии с тем, что находится в этом файле.Может быть, что-то вроде следующего.Эта версия избавила бы от необходимости перечислять префиксы в операторе if, но она не состоялась бы, если бы в файле были другие элементы.

values = {globals()[x]:x for x in dir() if not x.endswith('__')}

Конечно, вы могли бы сделать что-то более сложное, например проверитьслучайно повторенные значения.

1 голос
/ 15 февраля 2012

В итоге я оставил постоянные значения в модуле и создал dict. Модуль имеет значение ip_addr.py (значения взяты из linux / if_addr.h), поэтому при построении структур для отправки в ядро ​​я могу использовать if_addr.IFA_LABEL и разрешать ответы с помощью if_addr.values[2]. Я надеюсь, что это самое простое решение, поэтому, когда мне придется взглянуть на это снова через год + это легко понять: p

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7
__IFA_MAX      =  8

values = {
           IFA_UNSPEC    : 'IFA_UNSPEC',
           IFA_ADDRESS   : 'IFA_ADDRESS',
           IFA_LOCAL     : 'IFA_LOCAL',
           IFA_LABEL     : 'IFA_LABEL',
           IFA_BROADCAST : 'IFA_BROADCAST',
           IFA_ANYCAST   : 'IFA_ANYCAST',
           IFA_CACHEINFO : 'IFA_CACHEINFO',
           IFA_MULTICAST : 'IFA_MULTICAST',
           __IFA_MAX     : '__IFA_MAX'
         }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...