Saltar al contenido

¿Cómo puedo agregar un comentario a un archivo YAML en Python?

No dejes de divulgar nuestro sitio y códigos en tus redes, necesitamos de tu ayuda para aumentar nuestra comunidad.

Solución:

dentro de tu with bloque, puede escribir lo que quiera en el archivo. Ya que solo necesita un comentario en la parte superior, agregue una llamada a f.write() antes de llamar a ruamel:

with open('test.yml', "w") as f:
    f.write('# Data for Class An')
    ruamel.yaml.dump(
        d, f, Dumper=ruamel.yaml.RoundTripDumper,
        default_flow_style=False, width=50, indent=8)

Eso es posible en principio, porque puede hacer un recorrido de ida y vuelta de tales comentarios de “inicio de archivo”, pero no está bien soportado en el ruamel.yaml 0.10 actual y ciertamente no cuando “comienza desde cero” (es decir, no se cambia un archivo existente). expediente). En la parte inferior hay una solución fácil y relativamente buena, pero primero me gustaría presentar una solución fea y un paso a paso de cómo hacer esto.

Feo:
La manera fea de hacer esto es simplemente agregar el comentario al archivo antes de escribirle los datos YAML. Eso es insertar:

f.write('# Data for Class An')

justo antes ruamel.yaml.dump(...)

Paso a paso:
Para insertar el comentario en la estructura de datos, por lo que el truco anterior no es necesario, primero debe asegurarse de que su d los datos son un CommentedMap escribe. Si comparas la diferencia de eso d variable con una que tiene un comentario al cargar el YAML comentado nuevamente en c

import ruamel.yaml
from ruamel.yaml.comments import Comment, CommentedSeq, CommentedMap

d = CommentedMap()             # <<<<< most important
for m in ['B1', 'B2', 'B3']:
    d2 = 
    for f in ['A1', 'A2', 'A3']:
        d2[f] = CommentedSeq(['test', 'test2'])
        if f != 'A2':
            d2[f].fa.set_flow_style()
    d[m] = d2

yaml_str = ruamel.yaml.dump(d, Dumper=ruamel.yaml.RoundTripDumper,
                            default_flow_style=False, width=50, indent=8)

assert not hasattr(d, Comment.attrib)  # no attribute on the CommentedMap

comment = 'Data for Class A'
commented_yaml_str = '# ' + comment + 'n' + yaml_str
c = ruamel.yaml.load(commented_yaml_str, Loader=ruamel.yaml.RoundTripLoader)
assert hasattr(c, Comment.attrib)  # c has the attribute
print c.ca                         # and this is what it looks like
print d.ca                         # accessing comment attribute creates it empty
assert hasattr(d, Comment.attrib)  # now the CommentedMap has the attribute

Esto imprime:

Comment(comment=[None, [CommentToken(value=u'# Data for Class An')]],
  items=)
Comment(comment=None,
  items=)

A Comment tiene un attribute comment que debe configurarse en una lista de 2 elementos que consta del comentario EOL (siempre solo uno) y una lista de comentarios de línea anteriores (en forma de CommentTokens)

Para crear un CommentToken, necesita un StartMark (falso) que indique en qué columna comienza:

from ruamel.yaml.error import StreamMark
start_mark = StreamMark(None, None, None, 0, None, None)  # column 0

Ahora puedes crear el token:

from ruamel.yaml.tokens import CommentToken

ct = CommentToken('# ' + comment + 'n', start_mark, None)

Asigne el token como el primer elemento de la lista anterior en su CommentedMap:

d.ca.comment = [None, [ct]]
print d.ca   # in case you want to check

te dio:

Comment(comment=[None, [CommentToken(value='# Data for Class An')]],
  items=)

Y finalmente:

print ruamel.yaml.dump(d, Dumper=ruamel.yaml.RoundTripDumper)  

da:

# Data for Class A
B1:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2
B2:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2
B3:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2

Por supuesto, no es necesario crear el c objeto, eso es sólo para ilustración.

lo que debes usar: Para hacer que todo el ejercicio sea un poco más fácil, puede olvidarse de los detalles y parchear en el siguiente método para CommentedBase una vez:

from ruamel.yaml.comments import CommentedBase

def set_start_comment(self, comment, indent=0):
    """overwrites any preceding comment lines on an object
    expects comment to be without `#` and possible have mutlple lines
    """
    from ruamel.yaml.error import StreamMark
    from ruamel.yaml.tokens import CommentToken
    if self.ca.comment is None:
        pre_comments = []
        self.ca.comment = [None, pre_comments]
    else:
        pre_comments = self.ca.comments[1]
    if comment[-1] == 'n':
        comment = comment[:-1]  # strip final newline if there
    start_mark = StreamMark(None, None, None, indent, None, None)
    for com in comment.split('n'):
        pre_comments.append(CommentToken('# ' + com + 'n', start_mark, None))

if not hasattr(CommentedBase, 'set_start_comment'): # in case it is there
    CommentedBase.set_start_comment = set_start_comment

y luego solo haz:

d.set_start_comment('Data for Class A')

Te mostramos las comentarios y valoraciones de los usuarios

Si guardas algún impasse y forma de mejorar nuestro ensayo eres capaz de escribir una explicación y con deseo lo analizaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *