”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 为什么你应该更多地使用 attrs

为什么你应该更多地使用 attrs

发布于2024-11-07
浏览:139

Why should you use attrs more

介绍

Python 的 attrs 库对于希望简化类创建并减少样板代码的开发人员来说是一个游戏规则改变者。这个库甚至受到 NASA 的信任。
attrs 由 Hynek Schlawack 于 2015 年创建,因其能够自动生成特殊方法并提供干净、声明性的方式来定义类,而迅速成为 Python 开发人员最喜欢的工具。
dataclasses 是 attrs 的一种子集。

为什么 attrs 有用:

  • 减少样板代码
  • 提高代码可读性和可维护性
  • 提供强大的数据验证和转换功能
  • 通过优化实施提高性能

2. 属性入门

安装:
要开始使用 attrs,您可以使用 pip:
安装它

pip install attrs

基本用法:
下面是一个如何使用 attrs 定义类的简单示例:

import attr

@attr.s
class Person:
    name = attr.ib()
    age = attr.ib()

# Creating an instance
person = Person("Alice", 30)
print(person)  # Person(name='Alice', age=30)

3. attrs的核心特性

一个。自动方法生成:

attrs 会自动为您的类生成 initrepreq 方法:

@attr.s
class Book:
    title = attr.ib()
    author = attr.ib()
    year = attr.ib()

book1 = Book("1984", "George Orwell", 1949)
book2 = Book("1984", "George Orwell", 1949)

print(book1)  # Book(title='1984', author='George Orwell', year=1949)
print(book1 == book2)  # True

b.具有类型和默认值的属性定义:

import attr
from typing import List

@attr.s
class Library:
    name = attr.ib(type=str)
    books = attr.ib(type=List[str], default=attr.Factory(list))
    capacity = attr.ib(type=int, default=1000)

library = Library("City Library")
print(library)  # Library(name='City Library', books=[], capacity=1000)

c.验证器和转换器:

import attr

def must_be_positive(instance, attribute, value):
    if value 



4. 高级使用

一个。自定义属性行为:

import attr

@attr.s
class User:
    username = attr.ib()
    _password = attr.ib(repr=False)  # Exclude from repr

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, value):
        self._password = hash(value)  # Simple hashing for demonstration

user = User("alice", "secret123")
print(user)  # User(username='alice')

b.冻结的实例和槽:

@attr.s(frozen=True) # slots=True is the default
class Point:
    x = attr.ib()
    y = attr.ib()

point = Point(1, 2)
try:
    point.x = 3  # This will raise an AttributeError
except AttributeError as e:
    print(e)  # can't set attribute

c.工厂函数和初始化后处理:

import attr
import uuid

@attr.s
class Order:
    id = attr.ib(factory=uuid.uuid4)
    items = attr.ib(factory=list)
    total = attr.ib(init=False)

    def __attrs_post_init__(self):
        self.total = sum(item.price for item in self.items)

@attr.s
class Item:
    name = attr.ib()
    price = attr.ib(type=float)

order = Order(items=[Item("Book", 10.99), Item("Pen", 1.99)])
print(order)  # Order(id=UUID('...'), items=[Item(name='Book', price=10.99), Item(name='Pen', price=1.99)], total=12.98)

5. 最佳实践和常见陷阱

最佳实践:

  • 使用类型注释以获得更好的代码可读性和 IDE 支持
  • 利用验证器确保数据完整性
  • 对不可变对象使用冻结类
  • 利用自动方法生成来减少代码重复

常见陷阱:

  • 忘记在类上使用 @attr.s 装饰器
  • 过度使用可能是单独方法的复杂验证器
  • 不考虑大量使用工厂函数对性能的影响

6. attrs 与其他库的比较

图书馆 特征 表现 社区
属性 自动方法生成、具有类型和默认值的属性定义、验证器和转换器 比手动代码更好的性能 活跃社区
pydantic 数据验证和设置管理、自动方法生成、具有类型和默认值的属性定义、验证器和转换器 表现良好 活跃社区
数据类 内置于 Python 3.7 中,使它们更易于访问 与 Python 版本相关 内置Python库

属性和数据类比 pydantic1.

与数据类的比较:

  • attrs 功能更加丰富且灵活
  • 数据类内置于 Python 3.7 中,使它们更易于访问
  • attrs 在大多数情况下具有更好的性能
  • 数据类与 Python 版本相关,而 attrs 作为外部库可以与任何 Python 版本一起使用。

与pydantic的比较:

  • pydantic 专注于数据验证和设置管理
  • attrs 更通用,并且与现有代码库集成得更好
  • pydantic 具有内置 JSON 序列化,而 attrs 需要额外的库

何时选择属性:

  • 对于具有自定义行为的复杂类层次结构
  • 当您需要对属性定义进行细粒度控制时
  • 对于需要 Python 2 兼容性的项目(尽管现在不太相关)

7. 性能和实际应用

表现:
由于其优化的实现,attrs 通常比手动编写的类或其他库提供更好的性能。

真实示例:

from attr import define, Factory
from typing import List, Optional

@define
class Customer:
    id: int
    name: str
    email: str
    orders: List['Order'] = Factory(list)

@define
class Order:
    id: int
    customer_id: int
    total: float
    items: List['OrderItem'] = Factory(list)

@define
class OrderItem:
    id: int
    order_id: int
    product_id: int
    quantity: int
    price: float

@define
class Product:
    id: int
    name: str
    price: float
    description: Optional[str] = None

# Usage
customer = Customer(1, "Alice", "[email protected]")
product = Product(1, "Book", 29.99, "A great book")
order_item = OrderItem(1, 1, 1, 2, product.price)
order = Order(1, customer.id, 59.98, [order_item])
customer.orders.append(order)

print(customer)

8. 结论和行动呼吁

attrs 是一个功能强大的库,可以简化 Python 类定义,同时提供强大的数据验证和操作功能。它能够减少样板代码、提高可读性和增强性能,这使其成为 Python 开发人员的宝贵工具。

社区资源:

  • GitHub 存储库:https://github.com/python-attrs/attrs
  • 文档:https://www.attrs.org/
  • PyPI 页面:https://pypi.org/project/attrs/

在您的下一个项目中尝试 attrs 并亲身体验它的好处。与社区分享您的经验并为其持续发展做出贡献。快乐编码!


  1. https://stefan.sofa-rockers.org/2020/05/29/attrs-dataclasses-pydantic/↩

版本声明 本文转载于:https://dev.to/soumendrak/why-should-you-use-attrs-more-4dim?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • JavaScript计算两个日期之间天数的方法
    JavaScript计算两个日期之间天数的方法
    How to Calculate the Difference Between Dates in JavascriptAs you attempt to determine the difference between two dates in Javascript, consider this s...
    编程 发布于2025-07-13
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-07-13
  • 如何在其容器中为DIV创建平滑的左右CSS动画?
    如何在其容器中为DIV创建平滑的左右CSS动画?
    通用CSS动画,用于左右运动 ,我们将探索创建一个通用的CSS动画,以向左和右移动DIV,从而到达其容器的边缘。该动画可以应用于具有绝对定位的任何div,无论其未知长度如何。问题:使用左直接导致瞬时消失 更加流畅的解决方案:混合转换和左 [并实现平稳的,线性的运动,我们介绍了线性的转换。这...
    编程 发布于2025-07-13
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-07-13
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-07-13
  • Java数组中元素位置查找技巧
    Java数组中元素位置查找技巧
    在Java数组中检索元素的位置 利用Java的反射API将数组转换为列表中,允许您使用indexof方法。 (primitives)(链接到Mishax的解决方案) 用于排序阵列的数组此方法此方法返回元素的索引,如果发现了元素的索引,或一个负值,指示应放置元素的插入点。
    编程 发布于2025-07-13
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符提取最后一行,在Postgresql中,您可能需要遇到与在数据库中的每个不同标识相关的信息中提取信息的情况。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: ...
    编程 发布于2025-07-13
  • 用户本地时间格式及时区偏移显示指南
    用户本地时间格式及时区偏移显示指南
    在用户的语言环境格式中显示日期/时间,并使用时间偏移在向最终用户展示日期和时间时,以其localzone and格式显示它们至关重要。这确保了不同地理位置的清晰度和无缝用户体验。以下是使用JavaScript实现此目的的方法。方法:推荐方法是处理客户端的Javascript中的日期/时间格式化和时...
    编程 发布于2025-07-13
  • 在GO中构造SQL查询时,如何安全地加入文本和值?
    在GO中构造SQL查询时,如何安全地加入文本和值?
    在go中构造文本sql查询时,在go sql queries 中,在使用conting and contement和contement consem per时,尤其是在使用integer per当per当per时,per per per当per. 在GO中实现这一目标的惯用方法是使用fmt.spr...
    编程 发布于2025-07-13
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-07-13
  • Java的Map.Entry和SimpleEntry如何简化键值对管理?
    Java的Map.Entry和SimpleEntry如何简化键值对管理?
    A Comprehensive Collection for Value Pairs: Introducing Java's Map.Entry and SimpleEntryIn Java, when defining a collection where each element com...
    编程 发布于2025-07-13
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-07-13
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-07-13
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-07-13
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-07-13

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3