簡體   English   中英

Python 數據類,一個屬性引用另一個

[英]Python dataclass, one attribute referencing other

@dataclass
class Stock:
    symbol: str
    price: float = get_price(symbol)

一個dataclass屬性可以訪問另一個嗎? 在上面的示例中,可以通過提供代碼和價格來創建Stock 如果未提供價格,則默認為我們從某些 function get_price獲得的價格。 有沒有辦法引用符號?

此示例生成錯誤NameError: name 'symbol' is not defined

您可以在此處使用__post_init__ 因為它會在__init__之后被調用,所以你的屬性已經被填充了,所以你可以在那里做任何你想做的事情:

from typing import Optional
from dataclasses import dataclass


def get_price(name):
    # logic to get price by looking at `name`.
    return 1000.0


@dataclass
class Stock:
    symbol: str
    price: Optional[float] = None

    def __post_init__(self):
        if self.price is None:
            self.price = get_price(self.symbol)


obj1 = Stock("boo", 2000.0)
obj2 = Stock("boo")
print(obj1.price)  # 2000.0
print(obj2.price)  # 1000.0

因此,如果用戶在實例化時沒有傳遞price ,則price為無。 所以你可以在__post_init__中檢查它並從get_price詢問它。

如果價格總是可以從符號推導出來,我會 go 和@property 保持代碼精簡,從外部看起來像是一個屬性:

def get_price(symbol):
    return 123

@dataclass
class Stock:
    symbol: str

@property
def price(self):
    return get_price(symbol)

stock = Stock("NVDA")
print(stock.price) # 123

如果您想要一個可設置的屬性,該屬性還具有從其他字段派生的默認值,您可能只想按照建議實現自己的__init____post_init__

如果這是您經常遇到的並且需要更復雜的方法來處理它,我建議您查看pydanticvalidator

from typing import Optional

from pydantic import validator
from pydantic.dataclasses import dataclass

def get_price(symbol):
    return 123.0

@dataclass
class Stock:
    symbol: str
    price: Optional[float] = None

    @validator('price')
    def validate_price(cls, v, values, **kwargs):
        return v or get_price(values["symbol"])


print(Stock("NVDA"))
#> Stock(symbol='NVDA', price=123.0)
print(Stock("NVDA", 456))
#> Stock(symbol='NVDA', price=456.0)

暫無
暫無

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

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