首頁 >後端開發 >Python教學 >Python中的資料類別是如何使用的?

Python中的資料類別是如何使用的?

WBOY
WBOY轉載
2023-04-23 17:22:071496瀏覽

Python3.7引進了dataclass。 dataclass裝飾器可以宣告Python類別為資料類別;資料類別適合用來儲存數據,一般而言它具有以下特徵:

  • 資料類別表示某種資料類型,資料物件代表一種特定類別的實體,包含了實體的屬性。

  • 同類型的物件之間可以進行比較;如,大於、小於或等於。

資料類別定義

就其本質而言,資料類別並沒有什麼特別之處,只是@dataclass裝飾器自動產生__repr__,init,__eq__等一系列方法。定義資料類別:

from dataclasses import dataclass

@dataclass
class A:
  normal: str
  defVal: int = 0

裝飾器

dataclass完整形式為(True為產生對應方法,False將不產生;若類別中已定義對應方法,則忽略此參數):

@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False):

  • init:預設會生成__init__方法;

  • repr:預設將產生__repr__方法;repr字串包含類別名稱、每個欄位名稱和其repr(按其類別中定義順序);

  • eq:預設會產生__eq__方法;如果傳入False,那麼__eq__方法將不會被dataclass添加,但會繼承object.__eq__(比較id);

  • order:預設不產生__gt__、__ge__、__lt__、__le__方法;

  • unsafe_hash:如果是False(預設),則根據eq和frozen的設定方式產生__hash__()方法(由內建的hash()使用)。

    • 如果eq和frozen都為真,預設情況會產生一個__hash__()方法;

    • 如果eq為真而frozen為假,則__hash__()將被設定為None,將其標記為不可散列(確實如此,因為它是可變的);

    • 如果eq為假,則__hash__()將保持不變,這表示將使用超類別的__hash__()方法(如果超類別是object,將回退到基於id的雜湊)。

  • frozen:如果為true,實例初始化後屬性將無法修改;

##field

#透過field方法,可自訂屬性:

dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None):

  • #default:如果提供,這將是該欄位的預設值。

  • default_factory:用於指定具有可變預設值的字段,必須是無參可呼叫物件;與default互斥(不可同時指定)。

  • init:如果為true(預設值),則該欄位作為參數包含在產生的__init__()方法中。

  • repr:如果為true(預設值),則該欄位包含在產生的__repr__()方法傳回的字串中。

  • compare:如果為true(預設值),則該欄位包含在產生的相等性和比較方法中(__eq__() , __gt__()等等)。

  • hash:可以是布林值或None:

  • #為None(預設值),則使用compare的值,這通常是預期的行為(不鼓勵將此值設為None以外的任何值);

  • 為true,則此欄位包含在生成的__hash__()方法中;

  • 設定hash=False但compare=True(即從hash中排除某個字段,但仍用於比較)的一個可能原因是,計算字段的hash代價很高;

  • metadata:這可以是映射或None;None被視為一個空的字典。這個值包含在MappingProxyType()中,使其成為唯讀,並暴露在Field物件上(是作為第三方擴充機制提供的)。

使用default_factory產生預設值:

from dataclasses import dataclass, field
import random

def build_marks() -> list:
    return [random.randint(0, 1000) for i in range(5)]

@dataclass(order=True)
class RandMark:
    marks: list = field(default_factory=build_marks)

r = RandMark() # 使用build_marks生成默认值
print(r)

初始化

透過dataclass裝飾器修飾後的類別:

  • #無需定義__init__,dataclass會自動處理;

  • 以易讀的方式預先定義成員屬性(及類型提示);並可定義預設值;

  • dataclass會自動加入一個__repr__函數;

#資料比較

透過@dataclass(order = True)可自動加入比較方法(__eq__和__lt__):

比較是透過屬性(字段)產生的元組,進行比較的;如上比較元組為(normal, defVale)

透過compare=False,可設定不用於比較的欄位:

@dataclass(order=True)
class Student:
    name: str = field(compare=False)
    score: float

s = [Student("mike", 90),
    Student("steven", 80),
    Student("orange", 70)
    ]
print(sorted(s)) # 只根据score排序

後處理

透過__post_init__可做後處理(在__init__返回前,自動呼叫):

from dataclasses import dataclass

@dataclass
class FloatNumber:
    val: float
    decimal: float = 0
    integer: float = 0

    def __post_init__(self):
        self.decimal, self.integer = math.modf(self.val)

f = FloatNumber(1.2) # decimal与integer自动赋值

# dataclasses方法

dataclasses內建屬性與方法:

  • fields(class_or_instance):傳回欄位Field物件的元組;

### #asdict(instance, *, dict_factory=dict):將資料類別轉換為字典,(name:value)對;############astuple(instance, *, tuple_factory=tuple):將資料類別轉換為元組;############replace(instance, **changes):建立與instance相同類型的新對象,changes為要修改的值。 ##########

以上是Python中的資料類別是如何使用的?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除