Введение строки 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 по определению. Его следует использовать только в том случае, если исходный файл полностью доверен. В общем, вы всегда должны "дезинфицировать свои входные данные" (предположите, что входные данные опасны, пока не доказано обратное).