首页 > 编程问答 >如何让 Pylance 理解 Pydantic 的 `allow_population_by_field_name` 初始化器?

如何让 Pylance 理解 Pydantic 的 `allow_population_by_field_name` 初始化器?

时间:2024-07-28 07:15:52浏览次数:14  
标签:python python-typing pydantic pyright

在我当前的项目中,我们使用 OpenAPI-to-TypeScript-API 生成器,它生成自动类型化函数,用于通过 Axios 调用 API 端点。在 Python 中,我们使用 snake_case 作为类属性,而在 TypeScript 中,我们使用 camelCase

使用此设置,我们发现别名属性 ( Field(..., alias="***") ) 与 || 相结合非常有用。 |property. allow_population_by_field_name = True 简单模型类示例:

问题是:为什么 Pylance 不明白我希望能够编写

from pydantic import BaseModel, Field

class MyClass(BaseModel):
    my_property: str = Field(..., alias="myProperty")

    class Config:
        allow_population_by_field_name = True


if __name__ == "__main__":
    my_object = MyClass(my_property="banana")

?请参阅下面的 vscode 截图: MyClass(my_property="banana") 是否有任何方法可以配置 Pylance/Pydantic/vscode 来更好地理解这一点?

Screenshot of error in VSCode

“只是生活”这是有问题的,因为在我们的代码中出现这样的红线会促进一种“心态”红色可能没问题”,所以他们失去了权力。

2023 年 5 月 8 日编辑:


我们找到了一种“规避”这个问题的方法,通过创建一个包含

的包装类。 pylance 似乎并没有注意到这一点,因此它的表现就好像它不存在一样。 alias_generator 我确信人们不会经常使用这样的系统,但这对我们的团队有帮助。它还允许我们不必到处写

= Field(..., alias="camelCase") everywhere.


你遇到的问题是Pylance的类型提示系统无法完全理解Pydantic的 allow_population_by_field_name 配置选项。

虽然Pylance已经很擅长理解Pydantic模型,但它仍然依赖于Python的类型提示系统,而这个系统本身并不知道Pydantic的这个特定行为。 当你设置了 allow_population_by_field_name = True 后,Pydantic实际上改变了它的初始化行为,允许使用别名来创建模型实例。 但是,Pylance 仍然认为你只能使用模型定义中的字段名,所以它会报错。

目前,没有直接的方法能让Pylance完全理解 allow_population_by_field_name 的行为。

不过,你可以尝试以下几种方法来解决这个问题,或者至少改善代码提示体验:

1. 使用 typing.cast : 你可以使用 typing.cast 来告诉 Pylance 你知道自己在做什么,它不应该报错。例如:

from typing import cast
from pydantic import BaseModel, Field

class MyClass(BaseModel):
    my_property: str = Field(..., alias="myProperty")

    class Config:
        allow_population_by_field_name = True


if __name__ == "__main__":
    my_object = cast(MyClass, MyClass(my_property="banana")) 

这样Pylance就不会再报错了,因为它会认为 my_object 的类型是 MyClass

2. 使用工厂函数 : 你可以创建一个工厂函数,该函数接受驼峰式命名法的参数并返回一个模型实例。

from pydantic import BaseModel, Field

class MyClass(BaseModel):
    my_property: str = Field(..., alias="myProperty")

    class Config:
        allow_population_by_field_name = True

def create_my_class(my_property: str) -> MyClass:
    return MyClass(my_property=my_property)

if __name__ == "__main__":
    my_object = create_my_class(my_property="banana")

3. 忽略错误 : 如果你确定你的代码是正确的,而且你不想使用上面的方法,你可以简单地忽略Pylance的错误提示。 你可以在VS Code的设置中禁用Pylance的错误提示,或者在代码中使用 # type: ignore 来忽略特定的错误提示。

4. 使用你提到的包装类 : 你找到的包装类方法确实是一种有效的规避方法。 虽然它可能不是最优雅的解决方案,但如果它对你的团队有效,那么继续使用它也 perfectly acceptable.

总结 :

  • Pylance 目前无法完全理解 Pydantic 的 allow_population_by_field_name 行为。
  • 你可以使用 typing.cast ,工厂函数或忽略错误来解决这个问题。
  • 你也可以继续使用你找到的包装类方法。

希望这些信息能帮到你!

标签:python,python-typing,pydantic,pyright
From: 75756665

相关文章

  • 当读取字节时,Python 将 \n 解释为 0xd0
    换行符被解释为Ð(0xd0)而不是(0x0a),我真的不知道如何解决这个问题。我也不知道从哪里开始。当尝试使用此代码时,它将0x0a读为0xd0。withopen(path,"rb")asroot:b_arr=root.read()+b""print("Processing...")buffer=""b_arr......
  • 在Python 3中获取范围的特定形式
    当获取range(1,100)时,我得到:[1,2,3,4,5...99]我需要像这个范围的zip之类的东西:[50,49,51,48,52,47,53...99]如何获取它?背景:这都是关于比特币谜题66的。首先我做了对过去已知的私钥进行线性回归预测,直到第65题为止。我......
  • Python:如何使用pyaudio或sounddevice等库进行自动录音?
    我想做一个项目,需要满足以下录音要求:程序启动后,会在后台不断检测麦克风的声音,当声音分贝大于一定值时打开录音流级别,当分贝低于一定级别时关闭录音流并保存为wav文件。我知道原理,但我无法使用这些库来实现。我想实现以上结果使用Python实现自动录音以下代......
  • 当我们创建一个在 https 服务器上获取和发送数据的 python 应用程序时,我们应该如何处
    python脚本使用Urllib3,我的服务器是在Node.js上编写的脚本。我担心(并且不清楚)证书:我是否需要将我的python应用程序上的证书另存为变量?例如我这样做了,http=urllib3.PoolManager(cert_reqs="CERT_REQUIRED",ca_certs='client-cert.pem')并且我不知道......
  • 使用 Python 进行 Web 抓取以获取数据 NoneType ERROR
    我正在努力为我的学校项目获取美元和价格。所以我决定为此使用网络抓取,但我有一个问题。当我尝试在服务器上使用我的代码时,它给我NoneType错误。它可以在googlecolab上使用,但我无法在我的电脑或服务器上使用。我该如何解决这个问题?网页抓取代码;defdolar():he......
  • Python 请求 - response.json() 未按预期工作
    我正在尝试从Python的requests模块调用API。在邮递员上,返回的响应标头中的Content-Type是application/json;charset=utf-8,响应json数据是我期望的样子。但是,在python上的API的get方法之后运行response.json()会抛出错误simplejson.errors......
  • Python 中的“样板”代码?
    Google有一个Python教程,他们将样板代码描述为“不幸的”,并提供了以下示例:#!/usr/bin/python#importmodulesusedhere--sysisaverystandardoneimportsys#Gatherourcodeinamain()functiondefmain():print'Hellothere',sys.argv[1]#Command......
  • Python 3.9.1 中的 collections.abc.Callable 是否有 bug?
    Python3.9包含PEP585并弃用typing模块中的许多类型,转而支持collections.abc中的类型,现在它们支持__class_getitem__例如Callable就是这种情况。对我来说,typing.Callable和collections.abc.Ca......
  • 列表子类的 Python 类型
    我希望能够定义列表子类的内容必须是什么。该类如下所示。classA(list):def__init__(self):list.__init__(self)我想包含键入内容,以便发生以下情况。importtypingclassA(list:typing.List[str]):#Maybesomethinglikethisdef__init__(self):......
  • Python 中类型友好的委托
    考虑以下代码示例defsum(a:int,b:int):returna+bdefwrap(*args,**kwargs):#delegatetosumreturnsum(*args,**kwargs)该代码运行良好,只是类型提示丢失了。在Python中使用*args,**kwargs来实现​​委托模式是很常见的。如果有一种方法可......