我有一个pydantic类,比如a类
我想在类上使用root_validator,我想要智能来帮助我键入类字段
所以我输入values参数为'Self'来获得智能感知,但智能感知假设值的字段是点可访问的,所以我把我的值包装在一个'dotdict'类中,允许我以这种方式访问它们
问题是mymyy抱怨我的dotdict类在每次访问
时没有属性X问题:如何使dotdict类的实例继承传递给构造函数的参数类型?
# myclasses.py
from mytools import dotdict
from pydantic import BaseModel, root_validator
from typing_extensions import Self
class A(BaseModel):
a: int
b: str
@root_validator
def validateA(cls, values: Self): # type: ignore[valid-type]
"""
Pylance complains about the type for 'values' being unknown
'values' is a dictionary with the fields of the class, so I type it as Self
Pylance is satisfied with this and ONLY NOW provides intellisense for 'values'
(notice my main goal is to get intellisense, but I also prefer the dot notation)
problem is that intellisense recons the fields of the class are dot accessible
so I wrap 'values' with the 'dotdict' class to make them dot accessible
THIS causes one big problem:
mypy complains on every 'values.field' like this:
"class 'dotdict' doesn't have an attribute 'field'
"""
values = dotdict(values) # type: ignore[valid-type]
assert values.a == int(values.b) , "simple assertion for show purposes"
return values
# mytools.py
class dotdict(dict): # type: ignore
"""
a dictionary that supports dot notation and returns 'None' on missing keys
"""
def __getattr__(self, key: str):
try:
v: Optional[Any] = self[key]
return v
except KeyError as ke:
return None
最后一点,我抱怨使用'Self'作为类型提示,因此使用# type: ignore,但我没有找到任何解决方案
谢谢!
编辑:"你为什么如此渴望智慧?"为什么不把你的类复制成一个TypedDict来用于智能感知呢?
对这些评论感到非常失望。如果你想提出一些想法,那是可以的,但不要破坏问题,也不要回答我没有问过的问题。
我有很大的模型,我有很大的root_validators,也许我可以做出其他的设计选择来减少它们的大小,但我现在唯一的问题是mymyy抛出一个"dotdict没有属性"在每个ACCESS中,我不想在每个ACCESS
上添加一个# type: ignore注释我注意到,如果我不抑制mymyy抛出的错误,因为我键入'values'作为Self,那么它不会抛出';dotdict属性';错误,所以我要忍受那个mymyerror (once pero root_validator)并继续键入我的值作为Self。显然,它会在下一个版本中自行解决(根据其中一个评论)
Thanks for nothing
正如我在评论中提到的,您无法控制values
的类型。它永远是一本字典。但是如果你真的非常需要那些智能感知自动建议,你可以创建自己的TypedDict
来反映实际的模型,并用它来注释values
。
from pydantic import BaseModel, root_validator
from typing import TypedDict
class DictA(TypedDict):
a: int
b: str
class A(BaseModel):
a: int
b: str
@root_validator
def validate_stuff(cls, values: DictA) -> DictA:
...
return values
如果您尝试在方法中执行类似values["a"].
的操作,您的IDE应该为您提供int
方法和属性的选择。注意,如果您的验证器是pre=True
,或者您允许任意的额外值,那么该注释仍然是一个谎言,字典可以包含任何内容。
但是,我不明白这有什么意义。如果你正在用它们做复杂的事情,你总是可以选择性地cast
你在中间变量的验证器中实际使用的值。几乎不需要让IDE知道所有字段的类型。
from pydantic import BaseModel, root_validator
from typing import Any, cast
class A(BaseModel):
a: int
b: str
@root_validator
def validate_stuff(cls, values: dict[str, Any]) -> dict[str, Any]:
val_a, val_b = cast(int, values["a"]), cast(str, values["b"])
...
return values
但这似乎也太过分了。我无法想象一个验证器会如此复杂,以至于你真的需要它。