继承构造函数参数的类类型



我有一个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

但这似乎也太过分了。我无法想象一个验证器会如此复杂,以至于你真的需要它。

最新更新