[英]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.