我最近不得不使用 Pydantic 來決議 JSON 檔案,并且考慮到專案的性質(這涉及從糟糕的掃描中提取一些舊檔案),事實證明我們將實作通過分析掃描生成 JSON 的模塊,并且我們也應該準備 Pydantic 模式來驗證和決議相同的 JSON 檔案。
現在,碰巧在許多情況下,檔案中的數字欄位被留空。由于這些欄位是數字,因此架構必須將欄位視為int. 如果掃描檔案并準備 JSON 輸出的模塊沒有找到特定欄位,當然,Pydantic 將簡單地使用引數為其生成一個默認值(零pydantic.Field)default。但是,當找到該欄位但將其留空時,就會出現問題。這是因為該parse_raw方法將嘗試決議該欄位,在其中找到一個空字串"",并引發一個ValidationError.
當然,一個簡單的解決方案是分析模塊確保所有數字欄位都映射到0它們是否為空。但這需要分析模塊了解輸入中的欄位,知道其中哪些是數字,并將它們映射到"0"from ""。
雖然這本質上不是問題,但我希望這項任務由pydantic. 一方面,如果我們已經在生成一個 Pydantic 模式,其中包含有關管道第二個模塊中欄位性質的資訊,那么將資料型別資訊也注入到第一個模塊中就變得多余了。另一方面,第一個模塊已經是一個帶有大量代碼的重型 CV 單元,因此向其中添加更多功能并使其進一步膨脹并不是我們想要做的。
我的意思是,如果有一個帶有模式的自動決議器,那么這個決議器應該能夠進行一些基本的映射是有道理的。如果決議器能夠為我們將所有空字串""實體映射到零實體"0"而我們不必擔心,那就太好了。這是我們正在尋找的功能。
考慮 JSON 檔案:
{
"a": ""
}
現在考慮這個類:
class A(BaseModel):
a: int = ...
如果我呼叫并提供我上面描述的這個檔案的方法,是否可以在 Python 代碼中用省略號標記的區域內放置任何東西,以便該方法回傳一個物件,而A.parse_file不是引發例外?{'a': 0}__dict__
我已經瀏覽過了pydantic.Field,但我找不到任何東西。
uj5u.com熱心網友回復:
有點難以理解,您的實際設定是什么,但如果我理解正確,您可以定義自己的模型。在這種情況下,您只需要撰寫一個自定義驗證器,并pre=True設定將任何空字串轉換為具有數字型別的欄位的數字零。
如果您想要一個或多或少通用的驗證器,您甚至可以將其設定為each_item=True. 然后它將與表示數字集合的欄位一起使用,例如list[float]。
這是一個完整的作業示例:
from numbers import Number
from typing import Any
from pydantic import BaseModel, validator
from pydantic.fields import ModelField
class Foo(BaseModel):
a: int
b: float
c: complex
d: list[float]
e: str
@validator("*", pre=True, each_item=True)
def empty_to_zero(cls, v: Any, field: ModelField) -> Any:
if issubclass(field.type_, Number) and v == "":
return field.type_(0)
return v
class Config:
arbitrary_types_allowed = True # only needed for `complex`
if __name__ == "__main__":
data = {
"a": "",
"b": "",
"c": "",
"d": ["3.14", ""],
"e": "Hi mom",
}
foo = Foo.parse_obj(data)
print(foo)
print(foo.dict())
輸出:
a=0 b=0.0 c=0j d=[3.14, 0.0] e='Hi mom'
{'a': 0, 'b': 0.0, 'c': 0j, 'd': [3.14, 0.0], 'e': 'Hi mom'}
Number這是基于任何合理的子類都將通過傳遞給建構式的正確初始化的假設,0我認為這不是一個大問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/529589.html
上一篇:如何決議標簽外的文本
