PyYaml Ожидает скаляр, но находит последовательность

Я пытаюсь загрузить пользовательские теги в свой код Python с помощью PyYaml. У меня нет большого опыта работы с загрузчиком, конструктором, парсером-представителем, преобразователем и дамперами pyYaml.

Ниже приведен мой код, который я мог придумать:

import yaml, os 
from collections import OrderedDict

root = os.path.curdir

def construct_position_object(loader, suffix, node):
    return loader.construct_yaml_map(node)

def construct_position_sym(loader, node):
    return loader.construct_yaml_str(node)

yaml.add_multi_constructor(u"!Position", construct_position_object)
yaml.add_constructor(u"!Position", construct_position_sym)


def main():
    file = open('C:\calcWorkspace\\13.3.1.0\PythonTest\YamlInput\Exception_V5.yml','r')
    datafile = yaml.load_all(file) 
    for data in datafile:          


        yaml.add_representer(literal, literal_presenter)
        yaml.add_representer(OrderedDict, ordered_dict_presenter)
        d = OrderedDict(l=literal(data))
        print yaml.dump(data,  default_flow_style=False)

    print datafile.get('abcd').get('addresses')

    yaml.add_constructor('!include', include)

def include(loader, node):
    """Include another YAML file."""

    global root
    old_root = root

    filename = os.path.join(root, loader.construct_scalar(node))
    root = os.path.split(filename)[0]

    data = yaml.load(open(filename, 'r'))
    root = old_root

    return data


class literal(str): pass

def literal_presenter(dumper, data):
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')


def ordered_dict_presenter(dumper, data):
    return dumper.represent_dict(data.items())


if __name__ == '__main__':
    main()

Это мой файл Yaml:

#sid: Position[SIK,sourceDealID,UTPI] 
sid: Position[1232546, 0634.10056718.0.1096840.0,]
ASSET_CLASS: "Derivative"
SOURCE_DEAL_ID: "0634.10056718.0.1096840.0"
INSTR_ID: "UKCM.L"
PRODUCT_TYPE_ID: 0
SOURCE_PRODUCT_TYPE: "CDS"
NOTIONAL_USD: 14.78
NOTIONAL_CCY: 
LOB:
PRODUCT_TYPE:
#GIM
UNDERLIER_INSTRUMENT_ID:
MTM_USD: 
MTM_CCY:
TRADER_SID:
SALES_PERSON_SID:
CLIENT_SPN:
CLIENT_UCN:
CLIENT_NAME:
LE: 
---
sid: Position[1258642, 0634.10056718.0.1096680.0,]
#sid: Position[1]
ASSET_CLASS: "Derivative"
SOURCE_DEAL_ID: "0634.10056718.0.1096840.0"
INSTR_ID: "UKCM.L"
PRODUCT_TYPE_ID: 0
SOURCE_PRODUCT_TYPE: "CDS"
NOTIONAL_AMT: 18.78
NOTIONAL_CCY: "USD"
LOB:
PRODUCT_TYPE:
UNDERLIER_INSTRUMENT_ID:
MTM_AMT: 
MTM_CCY:
TRADER_SID:
SALES_PERSON_SID:
CLIENT_SPN:
CLIENT_UCN:
CLIENT_NAME:
LE: 
--- 
# Excption documents to follow from here!!!

Exception:
  src_excp_id: 100001
  # CONFIGURABLE OBJECT, VALUE TO BE POPULATED RUNTIME (impact_obj COMES FROM CONFIG FILE)
  # VALUE STARTS FROM "!POSITION..." A USER DEFINED DATATYPE
  impact_obj: !Position [1232546, 0634.10056718.0.1096840.0,]
  # CONFIGURABLE OBJECT, VALUE TO BE POPULATED RUNTIME (rsn_obj COMES FROM CONFIG FILE)
  # VALUE STARTS FROM "_POSITION..." AN IDENTIFIER FOR CONFIGURABLE OBJECTS
  rsn_obj:    !Position [1258642, 0634.10056718.0.1096680.0,]
  exception_txt: "Invalid data, NULL value provided"
  severity: "High"   

Похоже, мой код не может идентифицировать определяемый пользователем тип данных !Position.

Любая помощь будет оценена

С Уважением.


person Vivek    schedule 03.09.2013    source источник


Ответы (1)


Необходимо изменить:

def construct_position_sym(loader, node):
    return loader.construct_yaml_str(node)

to :

def construct_position_sym(loader, node):
    return loader.construct_yaml_seq(node)

Поскольку объект position был последовательностью:

!Position [something, something]

Таким образом, конструктор должен был быть типом последовательности. Работает идеально!!!

person Vivek    schedule 03.09.2013