Разбор данных со значениями переменных - PullRequest
0 голосов
/ 21 июня 2019

У меня запутанная проблема с текущим проектом.По сути, я анализирую байтовый файл MIDI-файла (да, я должен сделать это так).MIDI-файлы структурированы таким образом, что данные для любого данного события в дорожке передаются через серию байтов, называемых «сообщением».MIDI-устройство знает, какой тип сообщения, на основе кода состояния, который составляет 1-3 байта в «сообщении», которые имеют определенные идентификаторы для определенных функций.

Мне нужно иметь возможность просматривать данные файла MIDI и записывать каждое «сообщение» как отдельный объект, чтобы я мог поместить их в последовательность для последующего использования.Проблема, с которой я сталкиваюсь, заключается в том, что по мере прохождения данных мне нужен эффективный способ прочитать каждый код состояния и сопоставить его с функцией, которую я написал, которая обрабатывает данные для этого типа сообщения.Сейчас я пытаюсь сделать следующее:

Во-первых, в любой заданной точке общего файла MIDI я просматриваю следующие 3 байта и сравниваю их со своим списком всех возможных трехбайтовых MIDI-файлов.коды состояния.Вот моя первая проблема.Для всех 3-байтовых кодов состояния (которые эквивалентны 6 шестнадцатеричным цифрам , которые часто используются при редактировании MIDI), 5-8-ые биты (второй шестнадцатеричный код)цифра) указывает канал MIDI, на который влияет текущее сообщение, которое является переменным и непредсказуемым.Поскольку я не могу предсказать канал, мне нужно воспринимать его как универсальное значение.Другими словами, мне нужно как-то уметь брать 6 цифр и игнорировать 2-ю, когда я сравниваю их со своим списком кодов.Я не думаю, что я объяснил это хорошо, поэтому вот пример:

6 шестнадцатеричный код внутри файла: Bn7800, где n - номер канала

Список 6Коды цифр: ['Bn7800','Bn7900','FF2001','FF2F00',...]

Мне нужно найти в этом списке правильный код, игнорируя 2-ю цифру, поскольку я не могу сказать, что это за время.

Мой другойПроблема в том, что, получив этот код, мне нужно вызвать конкретную функцию, написанную мной, которая обрабатывает этот код состояния.Я назвал все функции после кода состояния, которому они соответствуют, но проблема в том, что я не знаю, как взять строку, найденную в списке выше, и использовать ее для вызова функции.Например:

Мне нужно: Bn7800 В списке я нахожу это!Поэтому я храню его как новую переменную с именем stat_code = 'Bn7800'.Но тогда я не могу вызвать свою функцию таким образом -> self.stat_code(data), потому что stat_code - это не имя функции, которую я хочу.Я хочу, чтобы функция была названа в честь значения из stat_code.

Я не уверен, как можно вызвать функцию, основываясь на значении хранимой переменной.


Извините, если это сбивает с толку, мне трудно объяснить полностью, не пытаясь объяснить всю структуру файла MIDI.Пожалуйста, задавайте мне вопросы, если что-то неясно.Спасибо!


РЕДАКТИРОВАТЬ: Вот часть кода:

self.event_status_codes = {'ff0002': ff_00_02,'ff01': ff_01,'ff02': ff_02,'ff03': ff03,'ff04': ff_04,'ff05': ff_05,'ff06': ff_06,'ff07': ff_07,'ff2001': ff_20_01,'ff2f00': ff_2f_00,'ff5103': ff_51_03,'ff5405': ff_54_05,'ff5804': ff_58_04,'ff5902': ff_59_02,'ff7f': ff_7f,'8n': _8n,'9n': _9n,'an': an,'bn': bn,'cn': cn,'dn': dn,'en': en,'bn7800': bn_78_00,'bn7900': bn_79_00,'bn7a': bn_7a,'bn7b00': bn_7b_00,'bn7c00': bn_7c_00,'bn7d00': bn7d00,'bn7e': bn_7e,'bn7f00': bn_7f_00,'f0': f0,'f7': f7}

    if track_data[hbc:hbc+3] in self.event_status_codes:  
        status_code = track_data[hbc:hbc+3]
        self.status_code(track_data)

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

1 Ответ

0 голосов
/ 21 июня 2019

Я не уверен, как я могу вызвать функцию, основываясь на значении хранимой переменной.

Это выполнимо, если обратиться к функции по имени. В своем вопросе вы подразумеваете, что вызываете функцию на self, что облегчает ее: вы можете получить атрибут, содержащий указатель на функцию, используя функцию getattr(), а затем вызвать ее:

stat_code = 'B67800'
func = getattr(self, f'function_name_{stat_code}')
value = func()
# do stuff with value

Это также работает, если ваша функция является частью какого-либо другого модуля - просто замените self в этом примере на имя модуля, из которого вы будете вызывать его.

Если вам нужно вызвать глобально определенную функцию (не являющуюся частью модуля), вам может потребоваться индексировать в locals() или globals():

func = globals()[f'function_name_{stat_code}']
value = func()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...