|
4 | 4 |
|
5 | 5 | [](https://travis-ci.org/smarie/python-yamlable) [](https://smarie.github.io/python-yamlable/junit/report.html) [](https://codecov.io/gh/smarie/python-yamlable) [](https://smarie.github.io/python-yamlable/) [](https://pypi.python.org/pypi/yamlable/) |
6 | 6 |
|
| 7 | +PyYaml is a great library. However it is a bit hard for anyone to add the yaml capability to their classes. Its `YamlObject` helper class is a first step but it has two drawbacks: |
| 8 | + * one has to master PyYaml Loader/Dumper internal features to understand what they are doing |
| 9 | + * there is a mandatory metaclass, which can prevent wide adoption (multiple inheritance with metaclasses...) |
| 10 | + |
| 11 | +`yamlable` provides a very easy way for you to leverage PyYaml without suffering the complexity: simply inherit from `YamlAble`, decorate with `@yaml_info`, implement the abstract methods to write to / load from a dictionary, and you're set! |
| 12 | + |
| 13 | +In addition `yamlable` provides |
| 14 | + * a way to creade Yaml codecs for several object types at the same time (`YamlCodec`). |
| 15 | + * an alternative to `YamlAble` that relies strictly on `YamlObject`: `YamlObject2` |
7 | 16 |
|
8 | 17 |
|
9 | 18 | ## Installing |
|
14 | 23 |
|
15 | 24 | ## Usage |
16 | 25 |
|
17 | | -TODO |
| 26 | +Let's make a class yaml-able: we have to |
| 27 | + - inherit from `YamlAble` |
| 28 | + - decorate it with the `@yaml_info` annotation to declare the associated yaml tag |
| 29 | + - implement `from_yaml_dict` (class method called during decoding) and `to_yaml_dict` (instance method called during encoding) |
| 30 | + |
| 31 | +```python |
| 32 | +from yamlable import yaml_info, YamlAble |
| 33 | + |
| 34 | +@yaml_info(yaml_tag_ns='com.yamlable.example') |
| 35 | +class Foo(YamlAble): |
| 36 | + |
| 37 | + def __init__(self, a, b): |
| 38 | + """ Constructor """ |
| 39 | + self.a = a |
| 40 | + self.b = b |
| 41 | + self.irrelevant = 37 |
| 42 | + |
| 43 | + def __str__(self): |
| 44 | + """ String representation for prints """ |
| 45 | + return "Foo - " + str(dict(a=self.a, b=self.b)) |
| 46 | + |
| 47 | + def to_yaml_dict(self): |
| 48 | + """ This method is called when you call yaml.dump()""" |
| 49 | + return {'a': self.a, 'b': self.b} |
| 50 | + |
| 51 | + @classmethod |
| 52 | + def from_yaml_dict(cls, dct, yaml_tag): |
| 53 | + """ This method is called when you call yaml.load()""" |
| 54 | + return Foo(dct['a'], dct['b']) |
| 55 | +``` |
| 56 | + |
| 57 | +That's it! Let's check that our class is correct and allows us to create instances: |
| 58 | + |
| 59 | +```python |
| 60 | +>>> f = Foo(1, 'hello') |
| 61 | +>>> print(f) |
| 62 | + |
| 63 | +Foo - {'a': 1, 'b': 'hello'} |
| 64 | +``` |
| 65 | + |
| 66 | +The object directly has the `dump_yaml` (dumping to file) / `dumps_yaml` (dumping to string) methods: |
| 67 | + |
| 68 | +```python |
| 69 | +>>> print(f.dumps_yaml()) |
| 70 | + |
| 71 | +!yamlable/com.yamlable.example.Foo {a: 1, b: hello} |
| 72 | +``` |
| 73 | + |
| 74 | +The class directly has the `load_yaml` (load from file) / `loads_yaml` (load from string) methods |
| 75 | + |
| 76 | +```python |
| 77 | +>>> print(Foo.loads_yaml("!yamlable/com.yamlable.example.Foo {a: 0, b: hey}")) |
| 78 | + |
| 79 | +Foo - {'a': 0, 'b': 'hey'} |
| 80 | +``` |
| 81 | + |
| 82 | +See pyyaml help page for the various formatting arguments that you can use.. |
| 83 | + |
| 84 | +```python |
| 85 | +>>> print(f.dumps_yaml(default_flow_style=False)) |
| 86 | + |
| 87 | +!yamlable/com.yamlable.example.Foo |
| 88 | +a: 1 |
| 89 | +b: hello |
| 90 | +``` |
18 | 91 |
|
19 | | -See [Usage](./usage) for a complete example with exceptions handling and more. |
| 92 | +See [Usage](./usage) for other possibilities of `yamlable`. |
20 | 93 |
|
21 | 94 |
|
22 | 95 | ## Main features / benefits |
23 | 96 |
|
24 | | - * TODO |
| 97 | + * Add yaml-ability to any class easily through inheritance without metaclass (as opposed to `YamlObject`) and without knowledge of internal PyYaml loader/dumper logic. |
| 98 | + * Write codecs to support several types at a time with `YamlCodec` |
25 | 99 |
|
26 | 100 |
|
27 | 101 | ## See Also |
|
0 commit comments