簡體   English   中英

Python,yaml嵌套對象

[英]Python, yaml nested objects

我正在嘗試創建一個yaml格式,允許我在另一個對象內創建一個對象。 在這個示例中,我嘗試創建一個State Machine對象,同時在它們之間填充一些狀態和連接。

yaml.load("""
!statemachine {
     states: [
       !state { name: p1 },
       !state { name: p2 },
       !state { name: p3 },],
     connections:
      [!connection { 'pim' : [p1,p2]}]}
""")

!statemachine有一個構造函數,可以生成MyStateMachine類型的對象

!state有一個構造函數,它生成一個MyState類型的對象

!connection有一個構造函數,它應該使用名稱為p1的對象生成並添加一個連接

我這里有兩個問題:

1 - 在創建statemachine並且其中不存在狀態之后調用state的構造函數

2 - 檢索對象p1並在其上調用方法add_connection。

提前致謝

讓我們嘗試對象的真正pyyaml語法

myyaml.py:

import yaml,sys

class StateMachine(object):
    pass

class State(object):
    pass

class Connection(object):
    pass

if __name__ == '__main__':
    o = yaml.load("""
    !!python/object:myyaml.StateMachine {
         states: [
           !!python/object:myyaml.State { name: p1 },
           !!python/object:myyaml.State { name: p2 },
           !!python/object:myyaml.State { name: p3 },],
         connections:
          [       !!python/object:myyaml.Connection { 'pim' : [p1,p2]}]}
    """)
    print o.states[0].name
    print o.states[1].name
    print o.connections[0].pim
    sys.exit(0)

獲取:

p1
p2
['p1', 'p2']

永遠不要嘗試模塊的根塊中的yaml.load(),總是使用if __name__ == '__main__'或在一個函數中調用它,確保它將被調用一次。

請注意yaml聲明:

!!python/object:myyaml.State { name: p1 },

此時yaml嘗試再次導入myyaml.py,在另一個上下文中,並且將執行模塊根目錄中的所有代碼,如果你在模塊的根目錄中放入yaml.load或類似的東西,你可能遇到無限循環,或意外的結果。

補充pylover的答案 :如果在某些時候你需要更多控制序列化/反序列化過程,請嘗試yamlable 我為我們的一些生產代碼編寫了這個包,以便對yaml-to-object綁定進行更多控制。

在你的例子中:

import yaml
import sys
from yamlable import YamlAble, yaml_info


@yaml_info(yaml_tag_ns='myyaml')
class StateMachine(YamlAble):

    def __init__(self, states, connections):
        self.states = states
        self.connections = connections

    # def to_yaml_dict(self):
    #     return vars(self)
    #
    # @classmethod
    # def from_yaml_dict(cls, dct, yaml_tag):
    #     return StateMachine(**dct)


@yaml_info(yaml_tag_ns='myyaml')
class State(YamlAble):

    def __init__(self, name):
        self.name = name

    # def to_yaml_dict(self):
    #     return vars(self)
    #
    # @classmethod
    # def from_yaml_dict(cls, dct, yaml_tag):
    #     return State(**dct)


@yaml_info(yaml_tag_ns='myyaml')
class Connection(YamlAble):

    def __init__(self, pim):
        self.pim = pim

    # def to_yaml_dict(self):
    #     return vars(self)
    #
    # @classmethod
    # def from_yaml_dict(cls, dct, yaml_tag):
    #     return Connection(**dct)


if __name__ == '__main__':
    o = yaml.safe_load("""
    !yamlable/myyaml.StateMachine {
         states: [
           !yamlable/myyaml.State { name: p1 },
           !yamlable/myyaml.State { name: p2 },
           !yamlable/myyaml.State { name: p3 },],
         connections:
          [       !yamlable/myyaml.Connection { 'pim' : [p1,p2]}]}
    """)
    print(o.states[0].name)
    print(o.states[1].name)
    print(o.connections[0].pim)

    print(yaml.safe_dump(o))

    # Note: these also work
    # print(o.loads_yaml(""" ... """))
    # print(o.dumps_yaml())

    sys.exit(0)

如果需要更改默認行為(例如,僅轉儲某些字段,或更改其轉儲結構),或者在加載時執行某些自定義實例創建,請取消注釋相應的方法。

有關更多詳細信息,請參閱yamlable文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM