首页 > 编程问答 >如何使数据类中的属性只读?

如何使数据类中的属性只读?

时间:2024-07-28 07:32:48浏览次数:7  
标签:python python-dataclasses

假设我有一个这样的类:

class C:

    def __init__(self, stuff: int):
        self._stuff = stuff

    @property
    def stuff(self) -> int:
        return self._stuff

然后 stuff 是只读的:

c = C(stuff=10)
print(c.stuff)  # prints 10

并且

c.stuff = 2

按预期失败

AttributeError:无法设置属性

我怎样才能得到相同的使用数据类的行为?如果我还想有一个 setter ,我可以这样做:

@dataclass
class DC:
    stuff: int
    _stuff: int = field(init=False, repr=False)

    @property
    def stuff(self) -> int:
        return self._stuff

    @stuff.setter
    def stuff(self, stuff: int):
        self._stuff = stuff

但是如果没有 @stuff.setter 部分我怎么能做到呢?


你不能直接使数据类中的属性只读。数据类被设计用来简化数据的存储,默认情况下,它们使所有字段都可读和可写。

但是,有几种方法可以实现你想要的结果,而无需使用 @stuff.setter

1. 使用 InitVar 和后期初始化:

from dataclasses import dataclass, InitVar

@dataclass
class DC:
    stuff: InitVar[int]
    _stuff: int = field(init=False)

    def __post_init__(self, stuff: int):
        self._stuff = stuff

在这个方法中, stuff 作为初始化变量 ( InitVar ) 传递。 它不会直接成为类的属性,而是在 __post_init__ 方法中使用它来初始化私有属性 _stuff 。 这使 _stuff 在初始化后无法修改。

2. 使用只读属性和不同的属性名:

from dataclasses import dataclass, field

@dataclass
class DC:
    _stuff: int = field(repr=False)

    @property
    def stuff(self) -> int:
        return self._stuff

此方法使用不同的属性名 ( _stuff ) 存储值,并使用只读属性 ( stuff ) 来访问它。

3. 使用第三方库:

一些第三方库,例如 attrs pydantic ,提供了更强大的功能来定义只读属性和其他数据验证功能。

例如,使用 attrs

import attr

@attr.s(auto_attribs=True)
class DC:
    _stuff: int = attr.ib(init=False)

    @property
    def stuff(self) -> int:
        return self._stuff

    @stuff.setter
    def stuff(self, value: int):
        # 可以在这里添加验证逻辑
        self._stuff = value 

选择哪种方法取决于你的具体需求和偏好。 如果只需要简单的只读属性,第一种或第二种方法就足够了。 如果你需要更强大的验证或其他功能,那么 attrs pydantic 等第三方库可能是更好的选择。

标签:python,python-dataclasses
From: 61237131

相关文章

  • 在 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......
  • 当读取字节时,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......