2017-12-29 25 views
1

次は、Python 3.4.7、ruamel.yamlバージョン0.15.35で、私のために働いていません。ruamel.yamlは列挙型をエンコードできますか?

Neutral: <Speed.Neutral: 1> 

しかし.dump()が提起:私は完全に合理的なreprを取得

import sys 
import enum 

import ruamel.yaml 
from ruamel.yaml import yaml_object 
yaml = ruamel.yaml.YAML() 

@yaml_object(yaml) 
class Speed(enum.IntEnum): 
    Reverse = 0 
    Neutral = 1 
    Low = 2 
    Drive = 3 
    Park = 999 

print("Neutral:", repr(Speed.Neutral)) 

yaml.dump(Speed.Neutral, sys.stdout) 

ruamel.yaml.representer.RepresenterError: cannot represent an object: <enum 'Speed'> 

enum年代がサポートされていない場合、私はを拡張するために行うことができます何かがあります私が使用しているクラス(または私が作成したサブクラスenum.IntEnum)。ダンダー法?

答えて

2

enumを渡されていて、サポートされていません.VALUE呼び出す@classmethodを追加するアウトオブボックス基本的にdumpメソッドが安全であるため、任意のPythonオブジェクトをサポートしていないためです。その安全性は、標準ライブラリからタイプenumを除外します。あなたは何をすべき

ruamel.yaml documentationで説明したように、あなたのSpeedクラスにto_yamlclassmethodを追加します:

import sys 
import enum 

import ruamel.yaml 
from ruamel.yaml import yaml_object 
yaml = ruamel.yaml.YAML() 

@yaml_object(yaml) 
class Speed(enum.IntEnum): 
    Reverse = 0 
    Neutral = 1 
    Low = 2 
    Drive = 3 
    Park = 999 

    @classmethod 
    def to_yaml(cls, representer, node): 
     return representer.represent_scalar(
      u'!Speed', 
      '{}-{}'.format(node._name_, node._value_) 
     ) 

yaml.dump(Speed.Neutral, sys.stdout) 

与える:

!Speed Neutral-1 
... 

あなたはもちろん、あなたに文字列表現を適応させることができます(出力を読み込むためにfrom_yamlを追加してください)。

ドキュメントの例のようにyaml_tagを追加することはできません。これは、enumの値を妨げるためです。

0

私は値で列挙型を渡す必要があると思います。

https://docs.python.org/3/library/enum.html#programmatic-access-to-enumeration-members-and-their-attributes

yaml.dump(Speed.Neutral.value, sys.stdout) 

拡張の答えは、それが

http://yaml.readthedocs.io/en/latest/dumpcls.html

import sys 
import enum 
import ruamel.yaml 
from ruamel.yaml import yaml_object 
yaml = ruamel.yaml.YAML() 

@yaml_object(yaml) 
class Speed(enum.IntEnum): 
    Reverse = 0 
    Neutral = 1 
    Low = 2 
    Drive = 3 
    Park = 999 

    @classmethod 
    def to_yaml(cls, representer, node): 
     return representer.represent_scalar(u'!enum:', u'{.value}'.format(node)) 
+0

これは回避策ですが、型情報が失われます。これは、int型をエンコードするだけです。 YAMLは他のオブジェクトの型と値を保持することができます。それは列挙型のためにそうすることができるように感じる。 – pourhaus