AttributeError: asignación no permitida al campo compuesto “tarea” en el objeto de mensaje de protocolo

2 minutos de lectura

Estoy usando protocol-buffers python lib para enviar datos, pero tiene algunos problemas, así que

Traceback (most recent call last):
  File "test_message.py", line 17, in <module>
    ptask.task = task
  File "build\bdist.win32\egg\google\protobuf\internal\python_message.py", line
513, in setter
AttributeError: Assignment not allowed to composite field "_task" in protocol message object.

el src de la siguiente manera:

archivo de prototipo:

message task {
    required int32 id = 1;
    required string msg = 2;
}

message task_info {
    required task task = 1;
}

código pitón:

task = yacc.task()
task.id = 1000
task.msg = u"test"
ptask = yacc.task_info() 
ptask.task = task # this line happen the runtime error 

Avatar de usuario de John McFarlane
Juan McFarlane

Probar Copiado de:

ptask.task.CopyFrom(task)

  • @ Cu2S regla de oro de StackExchange: siempre al menos lea la primera dos respuestas!

    – John MacFarlane

    6 de agosto de 2020 a las 8:05

  • Esta es la respuesta. los MergeFrom mencionado en otras respuestas también puede ser útil a veces.

    – Ferrán Maylinch

    17 mayo 2021 a las 15:24

No sé búferes de protocolo pero eché un vistazo a los documentos y dice:

No puede asignar un valor a un campo de mensaje incrustado. En cambio, asignar un valor a cualquier campo dentro del mensaje secundario implica establecer el campo del mensaje en el principal.

Así que supongo que esto debería funcionar:

task = yacc.task()
task.id = 1000
task.msg = u"test"
ptask = yacc.task_info() 
ptask.task.id = task.id
ptask.task.msg = task.msg

  • Este es el sección de los documentos donde habla de eso. También menciona la CopyFrom método.

    – Ferrán Maylinch

    17 mayo 2021 a las 15:36

También soy nuevo en los búferes de protocolo y me enfrenté al mismo problema. He encontrado este método útil.

Creo que debería funcionar:

task = yacc.task()
task.id = 1000
task.msg = u"test"
ptask = yacc.task_info() 
ptask.task.MergeFrom(task)

  • CopyFrom() llama a MergeFrom() después de borrar el objeto

    –Mark Parris

    4 de mayo de 2020 a las 5:51

¿Ha sido útil esta solución?