ヤムルを解析し、特定のパスが常に文字列であると仮定します
質問
私はYAMLパーサーを使用しています http://pyyaml.org そして、特定のフィールドを常に文字列として解釈してほしいが、add_path_resolver()がどのように機能するかを理解することはできません。
例:パーサーは、「バージョン」がフロートであると想定しています。
network:
- name: apple
- name: orange
version: 2.3
site: banana
一部のファイルには、「バージョン:2」(intとして解釈されます)または「バージョン:2.3アルファ」(STRとして解釈されます)があります。
私は彼らに常にstrとして解釈されたいです。
yaml.add_path_resolver()は、「バージョン:、常にそれをstrとして解釈するとき)を指定させてくれるようにする必要がありますが、それはあまり文書化されていません。私の最良の推測は次のとおりです。
yaml.add_path_resolver(u'!root', ['version'], kind=str)
しかし、それはうまくいきません。
私のバージョンフィールドを常に文字列にする方法についての提案?
PSここに、さまざまな「バージョン」文字列の例とそれらの解釈方法がいくつかあります。
(Pdb) import yaml
(Pdb) import pprint
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': 2}
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2.3\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': 2.2999999999999998}
(Pdb) pprint.pprint(yaml.load("---\nnetwork:\n- name: apple\n- name: orange\nversion: 2.3 alpha\nsite: banana"))
{'network': [{'name': 'apple'}, {'name': 'orange'}],
'site': 'banana',
'version': '2.3 alpha'}
解決
これのための最も簡単なソリューションは、基本を使用しないことです .load()
(とにかく安全ではありません)が、 Loader=BaseLoader
, 、すべてのスカラーを文字列としてロードします。
import yaml
yaml_str = """\
network:
- name: apple
- name: orange
version: 2.3
old: 2
site: banana
"""
data = yaml.load(yaml_str, Loader=yaml.BaseLoader)
print(data)
与える:
{'network': [{'name': 'apple'}, {'name': 'orange'}], 'version': '2.3', 'old': '2', 'site': 'banana'}
他のヒント
現在の出典から:
# Note: `add_path_resolver` is experimental. The API could be changed.
それは完全ではないようです(まだ?)。その構文 します 仕事(私が知る限り)は次のとおりです。
yaml.add_path_resolver(u'tag:yaml.org,2002:str', ['version'], yaml.ScalarNode)
ただし、そうではありません。
暗黙のタイプのリゾルバーが最初にチェックされ、一致する場合、ユーザー定義のリゾルバーをチェックしないように見えます。見る Resolver.py 詳細については、関数を探してください resolve
).
私はあなたを変えることをお勧めします version
への入場
version: !!str 2.3
これは常に文字列に強制されます。