Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyYAML dump Python object without tags

How can I dump Python objects without tags using PyYAML? I have such class:

class Monster(yaml.YAMLObject):
    yaml_tag = u'!Monster'
    def __init__(self, name, hp, ac, attacks):
        self.name = name
        self.hp = hp
        self.ac = ac
        self.attacks = attacks

Then I try to dump:

print(yaml.dump(Monster(name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT'])))

And got the result:

!Monster
ac: 16
attacks: [BITE, HURT]
hp: [3, 6]
name: Cave lizard

But the desired result is:

ac: 16
attacks: [BITE, HURT]
hp: [3, 6]
name: Cave lizard

How can I get this?

like image 793
Oleksandr Yarushevskyi Avatar asked Jan 28 '23 16:01

Oleksandr Yarushevskyi


1 Answers

Since you don't want to emit the tags, you should change the method that does that into a no-op:

import yaml
import sys

class Monster(yaml.YAMLObject):
    yaml_tag = u'!Monster'
    def __init__(self, name, hp, ac, attacks):
        self.name = name
        self.hp = hp
        self.ac = ac
        self.attacks = attacks

def noop(self, *args, **kw):
    pass

yaml.emitter.Emitter.process_tag = noop

yaml.dump([
    Monster(name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT']),
    Monster(name='Sméagol', hp=400, ac=14, attacks=['TOUCH','EAT-GOLD']),
], sys.stdout, allow_unicode=True)

which gives:

- ac: 16
  attacks: [BITE, HURT]
  hp: [3, 6]
  name: Cave lizard
- ac: 14
  attacks: [TOUCH, EAT-GOLD]
  hp: 400
  name: Sméagol

Please note that using print(yaml.dump()) is inefficient in time and memory. PyYAML has a streaming interface, so you should directly use it instead of streaming to a buffer and then streaming the buffer using print()

like image 59
Anthon Avatar answered Mar 04 '23 07:03

Anthon