When I looked it up, there weren't any samples (even in English-speaking countries!), So it was easy.
I was writing code in Python that defines the behavior of a program in YAML, and I just wanted to write a process to create an object in YAML.
As far as I can see PyYAMLDocumentation, there is a ** tag **, which seems to do what I want, but there is no usage example anywhere. I don't know if it should be used or how to define it. Well I was in trouble.
So, suddenly it's the main subject. To add a tag, pass a value to the PyYAML module's global function, ʻadd_multi_constructor () `.
yaml.add_multi_constructor("tag:yaml.org,2002:var", var_handler)
# ...
def var_handler(loader, suffix, node=None):
#processing
If you write such code, it will react when the YAML file has the following tag and var_handler
will be called.
textvariable: !!var:StringVar
name: label
default: ""
Three parameters are passed to the function specified as an argument
: StringVar
MappingNode (value = [(ScalarNode (), ScalarNode ()), (ScalarNode (), ScalarNode ())])
So, if you return some value as the return value of the function, the tag part will be the value specified in the return value.
For example, in the above example, returning the character "Yes" is the same as writing textvariable: Yes
.
ʻAdd_multi_constructor ()` If you follow the behavior of the function, it seems that if you omit the Loader defined as a keyword argument, the function specified here will be added to the three classes Loader, FullLoader, and UnsafeLoader. So if you use SafeLoader ** no matter what you do here, no function will be added. ** **
When reading YAML, if you want to read only the tags defined by yourself, it is better to specify SafeLoader as an argument and add a function.
I had some other work to do, and I was a little worried about messing with SafeLoader directly, so I defined a new class that inherited SafeLoader.
class GeneratorLoader(yaml.SafeLoader):
def __init__(self, stream):
super().__init__(stream)
yaml.add_multi_constructor("tag:yaml.org,2002:var", GeneratorLoader.var_handler,
Loader=GeneratorLoader)
@staticmethod
def var_handler(loader, suffix, node=None):
pass
If you use the class created here as a Loader in the yaml.load ()
method, the tags will be processed.
Note that the functions defined in \ _ \ _ init \ _ \ _. Py of PyYAML such as yaml.load ()
do not have a function that receives an instance of Loader (all receive classes).
Therefore, if you want to use the Loader object created above after loading YAML, you need to call Loader # get_single_data ()
directly.
loader = GeneratorLoader(self.string)
struct = loader.get_single_data()
I'm working on it now, but I'm using it in the next module.
As of September 21, 2020, there is such a process in tksugar / generator.py
(may move the code later).
Recommended Posts