I'm trying to load a YAML that looks like this:
dist: !!opencv-matrix
rows: 380
cols: 380
dt: f
data: [ 0., 0., -1.88644529e+18, 2.45423365e+00, 11698176.,
2.03862047e+00, -8.85501460e+10, 2.54738545e+00, 1.71208843e+20,
...
2.44447327e+00 ]
The loading code is just:
import yaml
y = yaml.load(s)
where s is the YAML loaded into a string.
I get this error:
yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:opencv-matrix'
in "<string>", line 382, column 7:
dist: !!opencv-matrix
This is fair enough, so I add the constructor for that tag:
def opencv_matrix(loader, node):
mapping = loader.construct_mapping(node)
mat = np.array(mapping["data"])
mat.resize(mapping["rows"], mapping["cols"])
return mat
yaml.add_constructor(u"!!opencv-matrix", opencv_matrix)
y = yaml.load(s)
I still get the error. However, if I replace !!opencv_matrix with !opencv_matrix, then everything works.
What's going on here?
All YAML files (regardless of their association with Ansible or not) can optionally begin with --- and end with ... . This is part of the YAML format and indicates the start and end of a document. All members of a list are lines beginning at the same indentation level starting with a "- " (a dash and a space):
Summary. Items of a list in YAML are represented by preceding it with - (hyphen). Key value pairs in YAML are represented as <key>:<value> . YAML is case sensitive. YAML uses spaces and indentations to define document structure.
YAML - yaml vs yml file Yaml files created with yaml and yml file extensions, Both are the same in interpretation and syntax. Nowadays, there is no OS system level enforcement to have 3 letters in extensions. Most of the yaml users are using . yaml as their preferred choice.
YAML is better suitable for configuration than JSON, whereas JSON is suitable for serialization format and transferring the data for API. JSON is good for human readability and suitable for serialization. It is explicit and can transmit the data over HTTP.
Secondary tags like !!opencv-matrix
are actually shorthand for tag:yaml.org,2002:opencv-matrix
(mentioned in the reference card). It looks like PyYAML's add_constructor
method doesn't correctly handle this shorthand notation.
This may be a bug, depending on how secondary tags are interpreted (see second part below). I've submitted a bug report here, and hopefully it will be addressed.
Primary tags like !opencv-matrix
are defined explicitly, and loading seem to work without any problems in PyYAML.
It works for me if you replace !!opencv-matrix
with tag:yaml.org,2002:opencv-matrix
in the add_constructor
call.
As for the original question, AFAIK primary tags (!
) are for user-defined types, while secondary tags (!!
) are meant to represent standard language-independent types defined here (hence the long and fancy format).
If this is an OpenCV-generated file, then maybe it would probably be simpler if these tags were changed to primary tags in the application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With