จะกำหนดให้กับฟิลด์ที่ซ้ำได้อย่างไร?


93

ฉันใช้โปรโตคอลบัฟเฟอร์ใน python และฉันมีPersonข้อความ

repeated uint64 id

แต่เมื่อฉันพยายามกำหนดค่าให้มันเช่น:

person.id = [1, 32, 43432]

ฉันได้รับข้อผิดพลาด: Assigment not allowed for repeated field "id" in protocol message object จะกำหนดค่าให้กับฟิลด์ที่ซ้ำได้อย่างไร?

คำตอบ:


121

ตามเอกสารประกอบคุณไม่สามารถกำหนดให้กับฟิลด์ที่ซ้ำได้โดยตรง ในกรณีนี้คุณสามารถเรียกextendเพื่อเพิ่มองค์ประกอบทั้งหมดในรายการลงในฟิลด์ได้

person.id.extend([1, 32, 43432])

11
ในทำนองเดียวกันสำหรับการเพิ่มค่าเดียวการใช้งานเช่นappend() person.id.append(1)สิ่งนี้ใช้กับฟิลด์protobuf ใด ๆ repeated
Hindol

17
appendใช้ไม่ได้ถ้าฟิลด์นั้นเป็นประเภทข้อความแทนที่จะเป็นประเภทดิบ (เช่นสตริง, int32 ฯลฯ ) extendใช้งานได้กับประเภทข้อความ
abeboparebop

4
หากคุณต้องการเขียนทับฟิลด์ประเภทข้อความซ้ำคุณต้องลบก่อนแล้วจึงขยาย del person.siblings[:] person.siblings.extend([Person(), Person()])
Neil


1
อย่าลืมส่งอาร์กิวเมนต์เพื่อขยายเป็นอาร์เรย์ (หรือรายการ) ห่อด้วยวงเล็บหากคุณต้องการ!
Nicholas Gentile

35

หากคุณไม่ต้องการขยายแต่เขียนทับทั้งหมดคุณสามารถทำได้:

person.id[:] = [1, 32, 43432]

วิธีนี้จะใช้เพื่อล้างฟิลด์ทั้งหมด:

del person.id[:]

3
สำหรับประเภทประกอบซ้ำคุณไม่สามารถใช้ person.id [:] = [xxx] เพื่อกำหนดการแทนที่ คุณต้องลบทั้งหมดก่อนแล้วจึงขยาย
ospider

4

สำหรับประเภทคอมโพสิตซ้ำ ๆ นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน

del person.things[:]
person.things.extend([thing1, thing2, ..])

นำมาจากความคิดเห็นเหล่านี้ วิธีการกำหนดให้กับฟิลด์ที่ซ้ำ? วิธีกำหนดให้กับเขตข้อมูลซ้ำ?


0

หลังจากสูญเสียการนอนหลับไปมากโดยพยายามหาตัวอย่างพื้นฐานสำหรับการทำงานในฟิลด์ซ้ำ ๆ ในที่สุดฉันก็ได้รับมัน

ปัญหา:

  • สร้างเครื่องคิดเลข.pyที่มีสองฟังก์ชันคือสี่เหลี่ยมและตัวคูณ
  • ใช้ GRPC สร้างไฟล์ Proto สำหรับไฟล์เดียวกัน
  • เขียนเซิร์ฟเวอร์ไคลเอนต์
  • รันเซิร์ฟเวอร์และเรียกใช้ไคลเอ็นต์เพื่อให้ได้ผลลัพธ์ที่ถูกต้อง

ไฟล์ Proto:

syntax = "proto3";

message Number {
    int32 value = 1;
}

message NumList {
    string name = 1;
    repeated Number nums = 2;
}

service Calculator {
    rpc Multiplier(NumList) returns (Number) {}
    rpc Square(Number) returns (Number) {}
}

ตอนนี้ส่วนสี่เหลี่ยมเป็นเรื่องง่าย แต่สำหรับตัวคูณฉันต้องการส่งผ่านรายการ Numbers (เช่นเดียวกับประเภท Number ตามที่กำหนดในไฟล์โปรโต)

ปัญหาก็คือด้วยซ้ำฟิลด์ และนี่คือทางออกที่ดีที่สุดในระยะสั้น

การแก้ไขปัญหา:

import grpc

# import the generated classes
import calculator_pb2
import calculator_pb2_grpc
# open a gRPC channel
channel = grpc.insecure_channel('localhost:50051')

# create a stub (client)
stub = calculator_pb2_grpc.CalculatorStub(channel)
num_list = calculator_pb2.NumList()
num_list.name = 'MyFirstList'
n1 = num_list.nums.add()
n2 = num_list.nums.add()
n3 = num_list.nums.add()
n1.value = 10
n2.value = 20
n3.value = 30

assert len(num_list.nums) == 3

response = stub.Multiplier(num_list)
print(response.value)

ฟังก์ชันตัวคูณเครื่องคิดเลข (เนื่องจากจำเป็นต้องแสดง):

def multiplier(numlist, name):
    mul = 1
    for num in numlist:
        mul = mul * num.value
    print(f'Result of list {name}')
    return mul

หวังว่านี่จะช่วยใครบางคนได้ หวังว่านี่จะเป็นคำอธิบายที่ควรจะเป็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.