簡體   English   中英

重用數據類類型提示

[英]Reusing Dataclass Type Hints

我正在嘗試在我的 function 簽名中重用來自數據類的類型提示 - 也就是說,無需再次輸入簽名。

解決這個問題的最佳方法是什么?

from dataclasses import dataclass
from typing import Set, Tuple, Type

@dataclass
class MyDataClass:
    force: Set[Tuple[str, float, bool]]

# I've had to write the same type annotation in the dataclass and the
# function signature - yuck
def do_something(force: Set[Tuple[str, float, bool]]):
    print(force)

# I want to do something like this, where I reference the type annotation from
# the dataclass. But, doing it this way, pycharm thinks `force` is type `Any`
def do_something_2(force: Type["MyDataClass.force"]):
    print(force)

解決這個問題的最佳方法是什么?

PEP 484 為這種情況提供了一個明確的選擇

類型別名

類型別名由簡單的變量賦值定義:(...) 類型別名可能與注解中的類型提示一樣復雜——任何可以作為類型提示的東西都可以在類型別名中接受:

應用於您的示例,這相當於(Mypy 確認這是正確的)

from dataclasses import dataclass

Your_Type = set[tuple[str, float, bool]]


@dataclass
class MyDataClass:
    force: Your_Type


def do_something(force: Your_Type):
    print(force)

以上是使用 Python 3.9 及以后的Generic Alias Type編寫的。 由於typing.Settyping.Tuple已被棄用,語法更加簡潔和現代。



現在,根據Python 數據充分理解這一點 Model比看起來要復雜得多:

3.1。 對象、值和類型

每個 object 都有一個標識、一個類型和一個值。

你第一次嘗試使用Type會得到驚人的結果

>>> type(MyDataClass.force)

AttributeError: type object 'MyDataClass' has no attribute 'force'

This is because the builtin function type returns a type (which is itself an object) but MyDataClass is "a Class" (a declaration) and the "Class attribute" force is on the Class not on the type object of the class where type()尋找它。 注意數據 Model 的區別:

  • 課程

    這些對象通常充當它們自身新實例的工廠

  • Class 實例

    任意類的實例

相反,如果您檢查實例上的類型,您將得到以下結果

>>> init_values: set = {(True, "the_str", 1.2)}

>>> a_var = MyDataClass(init_values)

>>> type(a_var)
<class '__main__.MyDataClass'>

>>> type(a_var.force)
<class 'set'>

現在讓我們通過將type()應用於 Class 聲明__anotations__上的 __annotations__ 來force恢復類型 object(不是類型提示)(這里我們看到前面提到的通用別名類型)。 (這里我們確實檢查了 class 屬性force上的 object 類型)。

>>> type(MyDataClass.__annotations__['force'])
<class 'typing._GenericAlias'>

或者我們可以檢查 Class 實例上的注釋,並恢復我們習慣看到的類型提示。

>>> init_values: set = {(True, "the_str", 1.2)}
>>> a_var = MyDataClass(init_values)
>>> a_var.__annotations__

{'force': set[tuple[str, float, bool]]}

我不得不在數據類和 function 簽名中編寫相同的類型注釋 -

對於元組,注釋往往會變成長文字,這證明了為簡潔而創建目的變量是合理的。 但總的來說,顯式簽名更具描述性,這是大多數 API 的 go 的用途。

typing模塊

基本構建塊:

元組,通過列出元素類型來使用,例如Tuple[int, int, str] 空元組可以輸入為Tuple[()] 可以使用一種類型和省略號來表示任意長度的同質元組,例如Tuple[int, ...] (...這里是語法的一部分,一個文字省略號。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM