首页 > 编程问答 >为什么在 SQLAlchemy 或 Pydantic 等流行包中的 __init__ 外部定义属性?

为什么在 SQLAlchemy 或 Pydantic 等流行包中的 __init__ 外部定义属性?

时间:2024-07-28 07:33:58浏览次数:5  
标签:python sqlalchemy pydantic

我正在修改一个应用程序,尝试使用 Pydantic 作为我的应用程序模型,使用 SQLAlchemy 作为我的数据库模型。

我有现有的类,我在 __init__ 方法中定义了属性,就像我被教导的那样:

class Measure:
    def __init__(
        self,
        t_received: int,
        mac_address: str,
        data: pd.DataFrame,
        battery_V: float = 0
    ):
        self.t_received = t_received
        self.mac_address = mac_address
        self.data = data
        self.battery_V = battery_V

在 Pydantic 和 SQLAlchemy 中,按照文档,我必须在 __init__ 方法之外定义这些属性,例如在 Pydantic 中:

import pydantic

class Measure(pydantic.BaseModel):
    t_received: int
    mac_address: str
    data: pd.DataFrame
    battery_V: float

为什么会这样?这不是不好的做法吗?对该类的其他方法(类方法、静态方法、属性...)有任何影响吗?

请注意,这也是 非常不方便 因为当我实例化该类的对象时,我不'无法获得有关构造函数需要哪些参数的建议!


在 SQLAlchemy、Pydantic 和其他类似的库中,属性在 __init__ 方法之外定义,主要原因是为了实现 声明式数据定义 以及利用这些库提供的 元编程和数据验证 功能。

为什么不在 __init__ 中定义属性?

  • 声明式定义更清晰: 将属性定义移到类级别,可以清晰地展现类的结构和预期的数据类型。 这提高了代码的可读性和可维护性,因为一眼就能看出类的属性和类型,而无需深入研究 __init__ 方法。
  • 元编程和数据验证: SQLAlchemy 和 Pydantic 利用这些类级别定义来实现强大的功能,例如:
    • 数据验证: Pydantic 可以根据类型注解自动验证输入数据,确保数据类型和格式的正确性。
    • ORM 映射: SQLAlchemy 使用类属性来映射数据库表结构,自动处理数据库交互。
    • 序列化/反序列化: Pydantic 可以轻松地将模型实例序列化为 JSON 或其他格式,并在需要时反序列化回来。
  • 性能优势: 在某些情况下,声明式定义可以带来性能优势。例如,Pydantic 在创建实例时可以使用预定义的模型结构,而无需动态创建属性,从而提高效率。

这不是不好的做法吗?

在传统的 Python 类中,将属性定义在 __init__ 方法中是标准做法。 然而,对于 SQLAlchemy 和 Pydantic 这样的库,在类级别定义属性是推荐的做法,并且不会被视为不好的做法。 这是因为这些库的设计理念和目标与传统的 Python 类有所不同。

对其他方法的影响:

将属性定义在类级别并不会对其他方法(类方法、静态方法、属性等)产生负面影响。 你仍然可以在这些方法中访问和使用这些属性。

不便之处:

的确,在类级别定义属性可能会导致在实例化对象时缺少 IDE 提示。 然而,现代 IDE 和代码编辑器通常可以识别 Pydantic 和 SQLAlchemy 模型,并提供代码补全和类型提示。 此外,这些库的文档通常非常详细,可以帮助你了解如何正确地实例化对象。

总结:

虽然在 __init__ 之外定义属性可能看起来与传统的 Python 代码风格不同,但这是 SQLAlchemy 和 Pydantic 等库实现其强大功能所必需的。 这种做法提供了声明式定义、元编程、数据验证和其他优点,从而提高了代码的可读性、可维护性和功能性。

标签:python,sqlalchemy,pydantic
From: 74612809

相关文章

  • 在 Python 中读取部分 MP3 文件时处理“对于可用位计数来说太大”错误
    我正在尝试读取MP3文件的特定部分,但遇到错误:[src/libmpg123/layer3.c:INT123_do_layer3():1771]error:part2_3_length(1376)toolargeforavailablebitcount(760)可以访问音频文件此处我的环境是使用此Docker映像设置的:pytorc......
  • Python SQLAlchemy 2.0 使用 dataclass_transform 非必需字段类型
    我刚刚在一个新项目上安装了SQLAlchemy2.0,我正在尝试使我的模型尽可能类型安全。通过使用@typing_extensions.dataclass_transform,我已经能够实现我想要实现的大部分目标类型检查,但是当前所有字段都被标记为不需要。例如:@typing_extensions.dataclass_tran......
  • 如何让 Pylance 理解 Pydantic 的 `allow_population_by_field_name` 初始化器?
    在我当前的项目中,我们使用OpenAPI-to-TypeScript-API生成器,它生成自动类型化函数,用于通过Axios调用API端点。在Python中,我们使用snake_case作为类属性,而在TypeScript中,我们使用camelCase使用此设置,我们发现别名属性(Field(...,alias="***")......
  • 当读取字节时,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......