Введение строки YAML в скрипт Python

Я работаю над кодом Python, способным читать файл YAML и генерировать модель на основе правил в PySB.

Новое правило в файле YAML указывается так:

--- !rule
name: L_binds_R
reaction:
    L(unbound) + R(inactive) >> L(bound)%R(active)
rates:
    - Kf

При этом я создаю объект pyyaml ​​(pyyaml ​​- это пакет для работы с yaml в python) в python, а атрибут реакции хранится в виде строки.

Тогда правило в pysb должно быть указано как:

# Rule(name, reaction, constant)
Rule('L_binds_R', L(unbound) + R(inactive) >> L(bound)%R(active), kf)

Моя проблема заключается в том, что поле 'response' в yaml хранится в виде строки в объекте python, но pysb не принимает какой-либо другой формат, кроме простого текста.

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

Есть идеи, чтобы решить проблему?

1 ответ

Решение

Вы можете подойти к этому одним из двух способов: реструктурировать свою находку YAML для токенизации правил реакции или использовать eval в Python.

Правила токенизированной реакции

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

--- rule!
name: L_binds_R
reaction:
    reactant:
        name: L
        site: b
    reactant:
        name: R
        site: b
            state: inactive         
    product:
        name: L
        site: b
            bond: 1
    product:
        name: R
        site: b
            bond: 1
            state: active
    fwd_rate: kf

Затем вы можете написать синтаксический анализатор, чтобы перевести это в следующее правило PySB, построив ReactionPattern используя классы в ядре PySB (MonomerPattern, ComplexPattern и так далее):

Rule(‘L_binds_R’, L(b=None) + R(b='inactive') >> L(b=1) % R(b=(‘active’, 1)), kf)

Если у вас есть контроль над кодом, из которого исходит YAML, вам может быть проще либо напрямую выводить код PySB, либо, возможно, записывать в такой стандарт, как SBML, который PySB теперь может читать.

Возможно, вам будет полезно взглянуть на написанный мной анализатор языка PySB BioNetGen (BNGL), который создает модель PySB из XML-файла BioNetGen, в качестве примера того, как создать модель из внешнего файла.

С помощью eval

Альтернатива заключается в использовании eval, Хотя это и более простое решение, оно настоятельно не рекомендуется из соображений безопасности *. Однако, если все файлы YAML сгенерированы вами / вашим собственным кодом, и вы просто хотите быстрое исправление, это сделает это.

Вот пример:

# You would read these in from the YAML file, but I’ll just define
# the strings here for simplicity
reaction_name = "L_binds_R"
reaction_str = "L(b=None) + R(b='inactive') >> L(b=1) % R(b=('active', 1))"
reaction_fwd_rate = "Kf"

Rule(reaction_name, eval(reaction_str), eval(reaction_fwd_rate))
# Python output 
# (assumes Monomers L and R and parameter Kf are already defined):
# >>> Rule('L_binds_R', L(b=None) + R(b='inactive') >> L(b=1) % R(b=('active', 1)), Kf)

* Рассмотрим случай, когда ваш YAML содержал что-то вроде:

reaction:
    import shutil; shutil.rmtree('~')

Импортировать этот файл YAML и evalЕсли вы заполните это поле, ваш домашний каталог будет удален eval выполнит любой произвольный код Python по определению. Его следует использовать только в том случае, если исходный файл полностью доверен. В общем, вы всегда должны "дезинфицировать свои входные данные" (предположите, что входные данные опасны, пока не доказано обратное).

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