亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果沒有傳遞默認值,如何將默認值傳遞給變量?

如果沒有傳遞默認值,如何將默認值傳遞給變量?

aluckdog 2023-06-27 14:17:07
如果在字段中傳遞 None ,我可以在 Pydantic 中設置默認值嗎?我有以下代碼,但在我看來,這里的驗證器僅適用于模型的初始化,而不適用于其他情況。我的代碼:class User(BaseModel):     name: Optional[str] = ''     password: Optional[str] = ''     email: EmailStr        @validator('name')    def set_name(cls, name):        return name or 'foo'遇到的問題:user = User(name=None, password='some_password', email='[email protected]')print("Name is ", user.name)# > 'Name is foo'user.name = Noneprint("Name is ", user.name)# > 'Name is None'期望的輸出:user = User(name='some_name', password='some_password', email='[email protected]')user.name = Noneprint("Name is ", user.name)# > 'Name is foo'關于如何獲得所需的輸出有什么想法嗎?我認為擁有 getter 和 setter 將有助于解決這個問題。但是,我無法讓它們在 Pydantic 模型中工作:嘗試實現 getter 和 setter:class User(BaseModel):    name: Optional[str] = ''    password: Optional[str] = ''    email: EmailStr    def get_password(self):        return self.password    def set_password(self, password):        self.password = hash_password(password)    password = property(get_password, set_password)user = User(name='some_name', password='some_password', email='[email protected]')# > RecursionError: maximum recursion depth exceeded我還嘗試了屬性裝飾器:class User(BaseModel):     name: Optional[str] = ''     password: Optional[str] = ''     email: EmailStr    @property    def password(self):        return self._password    @password.setter    def password(self, password):        pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")        self._password = pwd_context.hash(password)user = User(name='some_name', email='[email protected]')user.password = 'some_password'# > ValueError: "User" object has no field "password"我還嘗試覆蓋init:class User(BaseModel):name: Optional[str] = ""password: Optional[str] = ""email: EmailStrdef __init__(self, name, password, email):    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")    password = pwd_context.hash(password)    super().__init__(name=name, password=password, email=email)
查看完整描述

3 回答

?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

您需要validate_assignment在模型配置中啟用選項:


from typing import Optional


from pydantic import BaseModel, validator



class User(BaseModel):

    name: Optional[str] = ''

    password: Optional[str] = ''


    class Config:

        validate_assignment = True


    @validator('name')

    def set_name(cls, name):

        return name or 'foo'



user = User(name=None, password='some_password', )

print("Name is ", user.name)



user.name = None

print("Name is ", user.name)

Name is  foo

Name is  foo


查看完整回答
反對 回復 2023-06-27
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

這個問題問得很好,所以我想提供一個更廣泛的例子,因為有很多方法可以動態分配值。

它僅在字段直接繼承數據類時才有效,更具體地說,這樣的東西是行不通的。


class User(BaseModel):

? ? name: Optional[str] = ""

? ? password: Optional[str] = ""


? ? class Config:

? ? ? ? validate_assignment = True


? ? @validator("name")

? ? def set_name(cls, name):

? ? ? ? return name or "bar"



user_dict = {"password": "so_secret"}

user_one = User(**user_dict)

Out: name='' password='so_secret'

始終驗證

出于性能原因,默認情況下,當未提供值時,不會為字段調用驗證器。但是在這種情況下,當您需要設置動態默認值時,我們可以將其設置為True


class User(BaseModel):

? ? name: Optional[str] = ""


? ? @validator("name", pre=True, always=True)

? ? def set_name(cls, name):

? ? ? ? return name or "bar"


In: user_one = User(name=None)

In: user_two = User()

Out: name='bar'

Out: name='bar'

但是always有一個重要的問題,因為我們使用always=True,pydantic會嘗試驗證默認的None,這會導致錯誤。


將 Pre 設置為True它將在發生驗證錯誤之前調用該字段,驗證器 pre 的默認設置為False,在這種情況下,它們將在字段驗證后調用。


使用配置

但這有一些缺點。


class User(BaseModel):

? ? name: Optional[str] = ""


? ? class Config:

? ? ? ? validate_assignment = True


? ? @validator("name")

? ? def set_name(cls, name):

? ? ? ? return name or "foo"


In:? user = User(name=None)

Out: name='foo'

當您將其設置為 None 時,它會正確返回動態值,但在某些情況下,例如完全返回動態值None,它會失敗。


In:? user = User()

Out: name=''

同樣,您需要進行設置才能使其發揮作用。


pre=True

always=True

使用default_factory

當您想要設置默認值(例如 UUID 或日期時間等)時,這非常有用。在這種情況下,您可能想要使用default_factory,但有一個很大的問題,您無法將Callable參數分配給 default_factory 。


class User(BaseModel):

? ? created_at: datetime = Field(default_factory=datetime.now)


In: user = User()

Out: created_at=datetime.datetime(2020, 8, 29, 2, 40, 12, 780986)


查看完整回答
反對 回復 2023-06-27
?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

分配默認值的多種方法


方法#1:id具有默認值的必填字段


class User(BaseModel):

? ? id: str = uuid.uuid4()

方法#2id具有默認值的可選字段


class User(BaseModel):

? ? id: Optional[str] = uuid.uuid4()

方法#3:id具有默認值的必填字段


class User(BaseModel):

? ? id: str = Field(default=uuid.uuid4())

方法#4:具有可id調用默認值的必填字段。這對于生成按需值(例如unique UUIDs或 )非常有用Timestamps。?

class User(BaseModel):

? ? id: str = Field(default_factory=uuid.uuid4)? # uuid.uuid4 is not executed immediately



查看完整回答
反對 回復 2023-06-27
  • 3 回答
  • 0 關注
  • 256 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號