Python 比較
描述 Python 如何比較物件。
由於 proto 資料的序列化方式,您不能依賴 proto 訊息例項的線表示來確定其內容是否與另一個例項相同。線格式 proto 訊息例項可能變化的幾種方式包括以下:
- protobuf 模式以某些方式發生變化。
- map 欄位以不同的順序儲存其值。
- 二進位制檔案使用不同的標誌構建(例如最佳化版與除錯版)。
- protobuf 庫已更新。
由於序列化資料可能以這些方式變化,因此確定相等性涉及其他方法。
比較方法
您可以使用標準 Python == 運算子比較 protocol buffer 訊息的相等性。使用 == 運算子比較兩個物件會使用 message.ListFields() 進行比較。在測試時,您可以使用 self.assertEqual(msg1, msg2)。
如果兩個訊息具有相同的型別且所有對應的欄位都相等,則它們被視為相等。不相等運算子 != 是 == 的精確反轉。
訊息相等性是遞迴的:要使兩個訊息相等,任何巢狀訊息也必須相等。
欄位相等性和存在性
欄位的相等性檢查是基於值的。對於具有顯式存在的欄位,欄位的存在性也考慮在內。
顯式設定為其預設值的欄位與未設定的欄位不被視為相等。
例如,考慮以下具有顯式存在欄位的訊息
edition = "2023";
message MyMessage {
int32 value = 1; // 'explicit' presence by default in Editions
}
如果您建立兩個例項,一個例項中 value 未設定,另一個例項中 value 顯式設定為 0,則它們將不相等
msg1 = MyMessage()
msg2 = MyMessage()
msg2.value = 0
assert not msg1.HasField("value")
assert msg2.HasField("value")
assert msg1 != msg2
同樣的原則也適用於子訊息欄位:未設定的子訊息不等於存在但為空的子訊息(子訊息類的預設例項)。
對於具有隱式存在的欄位,由於無法跟蹤存在性,因此該欄位始終透過其值與另一個訊息中的相應欄位進行比較。
這種行為,即存在性是相等性檢查的一部分,與某些其他語言或 protobuf 庫處理相等性的方式不同,在這些語言或庫中,未設定的欄位和設定為其預設值的欄位有時被視為等效(通常是為了線格式相容性)。在 Python 中,== 執行更嚴格的檢查。
其他欄位型別
- 如果重複欄位具有相同數量的元素且每個相應元素相等,則它們相等。元素的順序很重要。
- 如果對映欄位具有相同的鍵值對集合,則它們相等。鍵值對的順序無關緊要。
- 浮點欄位(
float和double)按值比較。請注意浮點比較的常見注意事項。