0

I'm trying to create an instance of a class from a yaml file which requires a numpy array as input to the constructor:

@yaml_object(yaml)   
class Elephant:
    yaml_tag = '!Elephant'
    
    def __init__(self, weight:np.array, height:float):
        self.weight = weight
        self.height = height
    
    def __repr__(self):
        return f'Elephant\n\tweight: {self.weight}, height: {self.height}'
        
    @classmethod
    def to_yaml(cls, representer, node):
        return representer.represent_omap(cls.yaml_tag,
                                          {'weight':node.weight.tolist(),
                                           'height':node.height}
                                         )
    @classmethod
    def from_yaml(cls, constructor, node):
        for m in constructor.construct_yaml_omap(node):
            pass
        weight = np.array(m['weight'])
        height = m['height']
        return cls(weight, height)

If I'm constructing the Elephant by using this testfile.yaml:

!Elephant
- weight:
  - - 3090.39990234375
    - 32452.0
  - - 3456.0
    - 3456.5
- height: 2.7

the new instance of the class has an empty weight attribute:

Elephant
    weight: [], height: 2.7

and the debugger tells me that the CommentedMap object m within the from_yaml method contains CommentedSeq objects which also have no values for weight.

I would think that this is an import problem but when I return m instead of cls(weight, height) and look at the contained values, suddenly the weight values are there:

CommentedOrderedMap([('weight', [[3090.39990234375, 32452.0], [3456.0, 3456.5]]), ('height', 2.7)])

I am completely lost. Can somebody help me how to get the values within the from_yaml method such that I can initialize the Elephant class properly with a numpy array and directly return an instance of the Elephant class?

Alex
  • 1
  • 2
  • What makes you think you should be calling `constructor.construct_yaml_omap`? As always with recurisve objects, you need to `yield` the object then fill it out. See e.g. [this answer](https://stackoverflow.com/a/72576805/1307905) – Anthon Nov 04 '22 at 13:07
  • Thanks for your fast reply! It seemed intuitive to me to use `constructor.construct_yaml_omap` since I used `represent_omap` in the `to_yaml` method. Sometimes one just needs a push in the right direction. I replaced the representer and constructor to represent_ and construct_mapping and now it works. The hint to previous answers helped a lot, thank you! – Alex Nov 04 '22 at 13:58

0 Answers0