pydantic學習與使用-5.dataclasses 數據類的學習使用


前言

python3.7 的新特性 dataclass,dataclass是指“一個帶有默認值的可變的namedtuple”,廣義的定義就是有一個類,它的屬性均可公開訪問。

dataclass簡介

dataclass 的屬性可以帶有默認值並能被修改,而且類中含有與這些屬性相關的類方法,那么這個類就可以稱為dataclass,
再通俗點講,dataclass就是一個含有數據及操作數據方法的容器。

  • 相比普通class,dataclass通常不包含私有屬性,數據可以直接訪問
  • dataclass的repr方法通常有固定格式,會打印出類型名以及屬性名和它的值
  • dataclass擁有__eq__和__hash__魔法方法
  • dataclass有着模式單一固定的構造方式,或是需要重載運算符,而普通class通常無需這些工作

如果用的python3.6版本,需先安裝dataclasses模塊,python3.7以上版本已經自帶了

pip install dataclasses==0.8

如果已經安裝過pydantic包,dataclasses模塊就已經一起裝好了。

簡單示例

dataclasses 數據類簡單示例

from dataclasses import dataclass
from typing import List


@dataclass
class User:
    """用戶數據類"""
    name: str
    age: int
    friends: List[int]


user = User(name="yo yo", age=20, friends=[2, 3, 4])
print(user)  # User(name='yo yo', age=20, friends=[2, 3, 4])
print(user.name)  # yo yo
print(user.age)   # 20
print(user.friends)  # [2, 3, 4]

dataclass 繼承的使用, 可以把前面的User 當成一個父類,子類繼承后可以覆蓋父類的屬性

from dataclasses import dataclass
from typing import List


@dataclass
class User:
    """用戶數據類"""
    name: str
    age: int
    friends: List[int]


@dataclass
class Sun(User):
    """子類"""
    name: str
    age: str
    friends: List[int]


a = Sun(name='yo', age='22', friends=[])
print(a)

pydantic 中使用 dataclasses

如果您不想使用pydantic 的 BaseModel 模塊,您可以在標准數據類上獲得相同的數據驗證(在 python 3.7 中引入)。
數據類在 python 3.6 中需下載第三方包 dataclasses 工作。

from datetime import datetime
from pydantic.dataclasses import dataclass


@dataclass
class User:
    id: int
    name: str = 'John Doe'
    signup_ts: datetime = None


user = User(id='42', signup_ts='2032-06-21T12:00')
print(user)
#> User(id=42, name='John Doe', signup_ts=datetime.datetime(2032, 6, 21, 12, 0))

pydantic.dataclasses.dataclassdataclasses.dataclass with validation 的替代品, 而不是pydantic.BaseModel 的替代品(在初始化掛鈎的工作方式上有一點不同)
在某些情況下,將pydanticis.BaseModel子類化是更好的選擇.

您可以使用所有標准的 pydantic 字段類型,生成的數據類將與標准庫 dataclass 裝飾器創建的數據類相同。

可以通過 訪問底層模型及其模式__pydantic_model__。此外,需要 a 的字段default_factory可以由 a 指定dataclasses.field

import dataclasses
from typing import List, Optional

from pydantic import Field
from pydantic.dataclasses import dataclass


@dataclass
class User:
    id: int
    name: str = 'John Doe'
    friends: List[int] = dataclasses.field(default_factory=lambda: [0])
    age: Optional[int] = dataclasses.field(
        default=None,
        metadata=dict(title='The age of the user', description='do not lie!')
    )
    height: Optional[int] = Field(None, title='The height in cm', ge=50, le=300)


user = User(id='42')
print(user.__pydantic_model__.schema())
"""
{
    'title': 'User',
    'type': 'object',
    'properties': {
        'id': {'title': 'Id', 'type': 'integer'},
        'name': {
            'title': 'Name',
            'default': 'John Doe',
            'type': 'string',
        },
        'friends': {
            'title': 'Friends',
            'type': 'array',
            'items': {'type': 'integer'},
        },
        'age': {
            'title': 'The age of the user',
            'description': 'do not lie!',
            'type': 'integer',
        },
        'height': {
            'title': 'The height in cm',
            'minimum': 50,
            'maximum': 300,
            'type': 'integer',
        },
    },
    'required': ['id'],
}
"""

pydantic.dataclasses.dataclass的參數與標准裝飾器相同,除了一個額外的關鍵字參數config與Config具有相同的含義。

嵌套數據類

數據類和普通模型都支持嵌套數據類。

from pydantic import AnyUrl
from pydantic.dataclasses import dataclass


@dataclass
class NavbarButton:
    href: AnyUrl


@dataclass
class Navbar:
    button: NavbarButton


navbar = Navbar(button=('https://example.com',))
print(navbar)
#> Navbar(button=NavbarButton(href=AnyUrl('https://example.com', scheme='https',
#> host='example.com', tld='com', host_type='domain')))

json 轉儲

Pydantic數據類沒有.json()功能。要將它們轉儲為 JSON,您需要使用pydantic_encoder以下內容:

import dataclasses
import json
from typing import List

from pydantic.dataclasses import dataclass
from pydantic.json import pydantic_encoder


@dataclass
class User:
    id: int
    name: str = 'John Doe'
    friends: List[int] = dataclasses.field(default_factory=lambda: [0])


user = User(id='42')
print(json.dumps(user, indent=4, default=pydantic_encoder))
"""
{
    "id": 42,
    "name": "John Doe",
    "friends": [
        0
    ]
}
"""


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM