13

タイトルはかなり自明です。

タプルをYAMLファイルに保存すると、次のようなものが表示されます。

ambient:  !!python/tuple [0.3, 0.3 ,0.3]

でロードしようとするとyaml.safe_load(file_object)、次のようなエラーが発生し続けます。

yaml.constructor.ConstructorError:  could not determine a constructor for the tag 'tag:yaml.org,2002:python/tuple'

何をする必要がありますか?

4

3 に答える 3

14

pyyamlでは、SafeLoaderにはPythonネイティブタイプのローダーは含まれていません。yaml仕様で定義されているタイプのみが含まれています。以下のインタラクションサンプルで、SafeLoaderとここのタイプを確認できます。Loader

Pythonタプルを追加する新しいLoaderクラスを定義できますが、他のタイプは定義できないため、それでもかなり安全です。

import yaml

class PrettySafeLoader(yaml.SafeLoader):
    def construct_python_tuple(self, node):
        return tuple(self.construct_sequence(node))

PrettySafeLoader.add_constructor(
    u'tag:yaml.org,2002:python/tuple',
    PrettySafeLoader.construct_python_tuple)

doc = yaml.dump(tuple("foo bar baaz".split()))
print repr(doc)
thing = yaml.load(doc, Loader=PrettySafeLoader)
print thing

その結果:

'!!python/tuple [foo, bar, baaz]\n'
('foo', 'bar', 'baaz')

SafeLoaderクラスとLoaderクラスに関連付けられているコンストラクターについては、以下を参照してください。

>>> yaml.SafeLoader.yaml_constructors
{None: <unbound method SafeConstructor.construct_undefined>,
 u'tag:yaml.org,2002:binary': <unbound method SafeConstructor.construct_yaml_binary>,
 u'tag:yaml.org,2002:bool': <unbound method SafeConstructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:float': <unbound method SafeConstructor.construct_yaml_float>,
 u'tag:yaml.org,2002:int': <unbound method SafeConstructor.construct_yaml_int>,
 u'tag:yaml.org,2002:map': <unbound method SafeConstructor.construct_yaml_map>,
 u'tag:yaml.org,2002:null': <unbound method SafeConstructor.construct_yaml_null>,
 u'tag:yaml.org,2002:omap': <unbound method SafeConstructor.construct_yaml_omap>,
 u'tag:yaml.org,2002:pairs': <unbound method SafeConstructor.construct_yaml_pairs>,
 u'tag:yaml.org,2002:seq': <unbound method SafeConstructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:set': <unbound method SafeConstructor.construct_yaml_set>,
 u'tag:yaml.org,2002:str': <unbound method SafeConstructor.construct_yaml_str>,
 u'tag:yaml.org,2002:timestamp': <unbound method SafeConstructor.construct_yaml_timestamp>}

>>> yaml.Loader.yaml_constructors
{None: <unbound method SafeConstructor.construct_undefined>,
 u'tag:yaml.org,2002:binary': <unbound method SafeConstructor.construct_yaml_binary>,
 u'tag:yaml.org,2002:bool': <unbound method SafeConstructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:float': <unbound method SafeConstructor.construct_yaml_float>,
 u'tag:yaml.org,2002:int': <unbound method SafeConstructor.construct_yaml_int>,
 u'tag:yaml.org,2002:map': <unbound method SafeConstructor.construct_yaml_map>,
 u'tag:yaml.org,2002:null': <unbound method SafeConstructor.construct_yaml_null>,
 u'tag:yaml.org,2002:omap': <unbound method SafeConstructor.construct_yaml_omap>,
 u'tag:yaml.org,2002:pairs': <unbound method SafeConstructor.construct_yaml_pairs>,
 u'tag:yaml.org,2002:python/bool': <unbound method Constructor.construct_yaml_bool>,
 u'tag:yaml.org,2002:python/complex': <unbound method Constructor.construct_python_complex>,
 u'tag:yaml.org,2002:python/dict': <unbound method Constructor.construct_yaml_map>,
 u'tag:yaml.org,2002:python/float': <unbound method Constructor.construct_yaml_float>,
 u'tag:yaml.org,2002:python/int': <unbound method Constructor.construct_yaml_int>,
 u'tag:yaml.org,2002:python/list': <unbound method Constructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:python/long': <unbound method Constructor.construct_python_long>,
 u'tag:yaml.org,2002:python/none': <unbound method Constructor.construct_yaml_null>,
 u'tag:yaml.org,2002:python/str': <unbound method Constructor.construct_python_str>,
 u'tag:yaml.org,2002:python/tuple': <unbound method Constructor.construct_python_tuple>,
 u'tag:yaml.org,2002:python/unicode': <unbound method Constructor.construct_python_unicode>,
 u'tag:yaml.org,2002:seq': <unbound method SafeConstructor.construct_yaml_seq>,
 u'tag:yaml.org,2002:set': <unbound method SafeConstructor.construct_yaml_set>,
 u'tag:yaml.org,2002:str': <unbound method SafeConstructor.construct_yaml_str>,
 u'tag:yaml.org,2002:timestamp': <unbound method SafeConstructor.construct_yaml_timestamp>}
于 2012-02-07T00:43:06.990 に答える
4

少なくともPyYAMLのドキュメントによると:

関数yaml.safe_loadは、この機能を整数やリストなどの単純なPythonオブジェクトに制限します。

ソースでわかるように、リストはやや広範ですが、は含まれていませんtag:yaml.org,2002:python/tuple

!!python/tupleYAMLファイルで型を生成している場合は、ではdump()なくを使用しているようsafe_dump()です。その場合は、によって作成されたファイルがによってロード可能であることが保証されていないため、おそらくload()の代わりに使用に切り替える必要があります。(の説明を参照してください)。safe_load()dump()safe_load()safe_dump()

于 2012-02-07T00:40:30.043 に答える
1

最新の答えを探している人のために。

現在、この問題はを使用して解決できますyaml.FullLoader

import yaml
yaml_file = open("path/to/filename.yaml", 'r')
loaded_yaml = yaml.load(yaml_file, Loader=yaml.FullLoader)

次に、以下のようにタプルとしてマークされたエントリは、問題なく正しく解析されます。

!!python/tuple [0.3, 0.3 ,0.3]

于 2021-06-02T14:38:08.847 に答える