在python脚本中引入YAML字符串

时间:2017-02-20 17:05:44

标签: python python-2.7 yaml pysb

我正在研究能够读取YAML文件并在PySB中生成基于规则的模型的python代码。

YAML文件中的新规则指定为:

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

有了这个,我在python中创建了一个pyyaml对象(pyyaml是一个在python中使用yaml的包),反应属性存储为字符串。

然后,pysb中的规则需要指定为:

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

我的问题依赖于“反应”这一事实。 yaml中的字段作为字符串存储在python对象中,但pysb不接受除纯文本之外的任何其他格式。

我已经检查了PySB,反应字段在任何情况下都不能成为字符串,我也没有找到如何在YAML中编写变量格式。

有什么想法解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

您可以采用以下两种方法之一:重构您的YAML查找以标记反应规则,或在Python中使用eval

标记反应规则

最好的方法是构建您的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规则,使用PySB核心中的类(ReactionPatternMonomerPattern等构建ComplexPattern):

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

如果您可以控制YAML来自的代码,您可能会发现直接输出PySB代码或者写入像PySB can now read这样的SBML标准更容易。

您可能会发现查看我编写的PySB BioNetGen language (BNGL) parser(从BioNetGen XML文件创建PySB模型),作为如何从外部文件创建模型的示例。

使用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代码。它只应在源文件完全受信任的情况下使用。一般来说,你应该始终"消毒你的输入" (假设输入是危险的,除非另有证明)。