根据另一个值设置默认值
Setting a default value based on another value
我有以下 Pydantic 模型:
from pydantic import BaseModel
import key
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str
我希望地址有一个 default_factory 作为一个函数,它接受一个 private_key 作为输入和 returns 一个地址。我的意图大致如下:
address: str = Field(default_factory=key.generate_address(self.private_key)
我怎样才能做到这一点?
我能够使用 root_validator
:
实现它
class Wallet(BaseModel):
address: str = None
private_key: str = Field(default_factory=key.generate_private_key)
@root_validator
def get_address(cls, values) -> dict:
if values.get("address") is None:
values["address"] = key.generate_address(values.get("private_key"))
return values
不确定这是否是通过
实现此目的的最佳方式
另一种选择是仅使用 @validator
,因为您可以在其中访问之前验证过的字段。来自 the documentation:
- validators are "class methods", so the first argument value they receive is the UserModel class, not an instance of UserModel.
- the second argument is always the field value to validate; it can be named as you please
- you can also add any subset of the following arguments to the signature (the names must match):
values
: a dict containing the name-to-value mapping of any previously-validated fields
示例:
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str = "" # "" seems better than None to use the correct type
@validator("address", always=True)
def get_address(cls, address: str, values: Dict[str, Any]) -> str:
if address is None:
return key.generate_address(values["private_key"])
return address
如果您只想为单个字段生成一个值,可以说 @validator
应该优于 @root_validator
。
必须考虑此方法的两个重要方面:
文档中的“先前验证的字段”意味着在您的情况下 private_key
必须在 address
之前定义。在验证的字段之后定义的字段值对验证器不可用。
如果验证的字段有默认值,而你仍然希望在这种情况下执行验证器,则必须使用always=True
.
我有以下 Pydantic 模型:
from pydantic import BaseModel
import key
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str
我希望地址有一个 default_factory 作为一个函数,它接受一个 private_key 作为输入和 returns 一个地址。我的意图大致如下:
address: str = Field(default_factory=key.generate_address(self.private_key)
我怎样才能做到这一点?
我能够使用 root_validator
:
class Wallet(BaseModel):
address: str = None
private_key: str = Field(default_factory=key.generate_private_key)
@root_validator
def get_address(cls, values) -> dict:
if values.get("address") is None:
values["address"] = key.generate_address(values.get("private_key"))
return values
不确定这是否是通过
实现此目的的最佳方式另一种选择是仅使用 @validator
,因为您可以在其中访问之前验证过的字段。来自 the documentation:
- validators are "class methods", so the first argument value they receive is the UserModel class, not an instance of UserModel.
- the second argument is always the field value to validate; it can be named as you please
- you can also add any subset of the following arguments to the signature (the names must match):
values
: a dict containing the name-to-value mapping of any previously-validated fields
示例:
class Wallet(BaseModel):
private_key: str = Field(default_factory=key.generate_private_key)
address: str = "" # "" seems better than None to use the correct type
@validator("address", always=True)
def get_address(cls, address: str, values: Dict[str, Any]) -> str:
if address is None:
return key.generate_address(values["private_key"])
return address
如果您只想为单个字段生成一个值,可以说 @validator
应该优于 @root_validator
。
必须考虑此方法的两个重要方面:
文档中的“先前验证的字段”意味着在您的情况下
private_key
必须在address
之前定义。在验证的字段之后定义的字段值对验证器不可用。如果验证的字段有默认值,而你仍然希望在这种情况下执行验证器,则必须使用
always=True
.