Evitar referencias en PyYAML.

Yo uso YAML con PyYAML. ¿Hay una manera de evitar las referencias * id002 después de volcar una estructura anidada? Para facilitar la lectura me gustaría ver los valores reales (tupla) allí.

Al intentar producir un mini ejemplo, noté que solo ocurre cuando uso el mismo objeto de identificación:

import yaml t = ("b", "c") x = {(1, t):1, (2, t):2, } print(yaml.dump(x)) 

Así que pensé que copy.copy() resolvería el problema, sin embargo, para las tuplas no parece funcionar 🙁 ¿Puedo crear una nueva tupla con un ID diferente?

El dumper PyYAML utiliza un método ignore_aliases para evitar que los tipos primitivos se “anclen” y “referencian” de esta manera. Puede anular ese método para ignorar siempre los alias independientemente de cualquier objeto pasado. Y, de forma predeterminada, la clase yaml.Loader se usa en yaml.load ¹:

 t = ("b", "c") x = {(1, t):1, (2, t):2, } yaml.Dumper.ignore_aliases = lambda *args : True yaml.dump(x, sys.stdout) 

te conseguirá:

 ? !!python/tuple - 1 - !!python/tuple [b, c] : 1 ? !!python/tuple - 2 - !!python/tuple [b, c] : 2 

De esa manera, no tiene que esforzarse al máximo y obtener tuplas con el mismo hash para verse diferente. Es posible que desee proporcionar el parámetro default_flow_style en yaml.load a False o True para obtener diferentes diseños de la salida.

La razón por la que no pudo hacer que esto funcione es que el representante coincide con el resultado de id() y que es el mismo para dos tuplas generadas por separado siempre que los elementos sean iguales.


¹ Solo probé esto con ruamel.yaml , del cual soy autor, es una versión mejorada de PyYAML, pero para esto ambos deberían funcionar igual.