标签: python-dataclasses

两个表面上相同的数据类不相等

我定义了以下数据类:

"""This module declares the SubtitleItem dataclass."""

import re

from dataclasses import dataclass
from time_utils import Timestamp

@dataclass
class SubtitleItem:
    """Class for storing all the information for
    a subtitle item."""
    index: int
    start_time: Timestamp
    end_time: Timestamp
    text: str

    @staticmethod
    def load_from_text_item(text_item: str) -> "SubtitleItem":
        """Create new subtitle item from their .srt file text.

        Example, if your .srt file contains the following subtitle item:

        ```
        3
        00:00:05,847 --> 00:00:06,916
        The robot.
        ```

        This function will return:

        ```
        SubtitleItem(
            index=3,
            start_time=Timestamp(seconds=5, milliseconds=847), …
Run Code Online (Sandbox Code Playgroud)

python python-dataclasses

5
推荐指数
1
解决办法
1322
查看次数

ValueError:不允许字段标题的可变默认 <class 'dict'>:使用 default_factory

我正在尝试使用新的 python 功能(数据类)。我正在尝试初始化变量,但出现错误:

raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'dict'> for field headers is not allowed: use default_factory
Run Code Online (Sandbox Code Playgroud)

我的代码:

@dataclass
class Application():
    __config = ConfigParser()
    __config.read('mydb.ini')
    __host: str = __config.get('db','dbhost')
    __user: str = __config.get('db','dbuser')
    __password: str = __config.get('db','dbpw')
    __database: str = __config.get('db','database')
    url: str = "https://xxxx.domain.com/"
    headers: str = {'X-ApiKeys':'accessKey=xxxxxxx;secretKey=xxxxx','Content-Type': 'application/json'}



def main(self):
    print(self.__host,self.__user,self.__password, self.__database)
   


app = Application()
if __name__=="__main__":
    app.main()
Run Code Online (Sandbox Code Playgroud)

初始化字典的正确方法是什么?

python python-3.x python-dataclasses

5
推荐指数
1
解决办法
1万
查看次数

如何在数据类中一起使用 match_args 和 kw_args ?

给出以下示例:

from dataclasses import dataclass

@dataclass
class Person:
    name: str = ""


@dataclass(kw_only=True)
class AnotherPerson:
    name: str = ""


print(Person.__match_args__)
print(AnotherPerson.__match_args__)
Run Code Online (Sandbox Code Playgroud)

运行时,您会得到以下信息:

('name',)
()
Run Code Online (Sandbox Code Playgroud)

根据dataclass match_args参数的文档(重点是我的):

match_args:如果为 true(默认为 True),将从生成的 __init__() 方法的参数列表中创建 __match_args__ 元组(即使未生成 __init__(),请参见上文)。如果为 false,或者类中已定义 __match_args__,则不会生成 __match_args__。

鉴于match_args默认值为 true,我认为__match_args__变量应该设置为方法中出现的值__init__,尽管关键字参数的情况似乎并非如此。这只是一个未记录的限制,还是我做错了什么?

__match_args__无论如何,我将如何在不明确写出这些元组的情况下生成它们?

python python-dataclasses python-3.10 structural-pattern-matching

5
推荐指数
1
解决办法
1481
查看次数

将dataclass的dataclass转换为json字符串

我有一个想要读取的 json 字符串,将其转换为我可以操作的对象,然后将其转换回 json 字符串。

我正在使用 python 3.10 数据类,该类的属性之一是另一个类(mySubClass)。当我打电话时 json.loads(myClass),我收到以下错误:TypeError: Object of type mySubClass is not JSON serializable.

有没有办法可以用它需要的一切(包括mySubClass )实例化数据类myClass,然后进行“初始化后操作”,将myClass.mySubClass转换为简单的 json str ?或者我以错误的方式处理这个问题?

我最初的目标是实现以下目标:

import json
from dataclasses import dataclass

@dataclass
mySubClass:
  sub_item1: str
  sub_item2: str

@dataclass
myClass:
  item1: str
  item2: mySubClass()

...
convert_new_jsonStr_toObj = json.loads(received_json_str, object_hook=lambda d: SimpleNamespace(**d))

...
#: Get new values/do "stuff" to the received json string

myClass_to_jsonStr = json.dumps(myClass(item1=convert_new_jsonStr_toObj.item1, item2=mySubClass(sub_item1=convert_new_jsonStr_toObj.sub_item1, sub_item2=convert_new_jsonStr_toObj.sub_item2)))

...
#: Final json will look …
Run Code Online (Sandbox Code Playgroud)

python oop json class python-dataclasses

5
推荐指数
1
解决办法
7384
查看次数

如何检查数据类是否被冻结?

有没有办法检查 Python 数据类是否已设置为冻结?如果不是,那么在dataclasses模块中使用像 is_frozen 这样的方法来执行此检查是否有价值?

例如

from dataclasses import dataclass, is_frozen

@dataclass(frozen=True)
class Person:
    name: str
    age: int

person = Person('Alice', 25)
if not is_frozen(person):
    person.name = 'Bob'
Run Code Online (Sandbox Code Playgroud)

检查数据类是否已设置为冻结的一种方法是尝试修改其属性之一并捕获FrozenInstanceError冻结时将引发的异常。

例如

from dataclasses import FrozenInstanceError
is_frozen = False
try:
    person.name = 'check_if_frozen'
except FrozenInstanceError:
    is_frozen = True
Run Code Online (Sandbox Code Playgroud)

但是,如果数据类未冻结,则属性将被修改,这可能只是为了执行检查而不需要的。

python python-dataclasses

5
推荐指数
1
解决办法
525
查看次数

动态将字段添加到数据类对象

我正在编写一个访问REST API的库。它返回带有用户对象的json。我将其转换为dict,然后将其转换为dataclass对象。问题在于,并非所有字段都是固定的。我想动态添加其他字段(在我的数据类中未指定)。我可以简单地为我的对象分配值,但是它们不会出现在对象表示中,并且dataclasses.asdict函数也不会将它们添加到结果字典中:

from dataclasses import asdict, dataclass

@dataclass
class X:
    i: int

x = X(i=42)
x.s = 'text'

x
# X(i=42)

x.s
# 'text'

asdict(x)
# {'i': 42}
Run Code Online (Sandbox Code Playgroud)

python field dynamic python-3.x python-dataclasses

4
推荐指数
2
解决办法
1026
查看次数

Python:更改数据类时验证输入

在Python 3.7中,这些新的“数据类”容器基本上类似于可变的namedtuple。假设我制作了一个要代表一个人的数据类。我可以通过如下__post_init__()函数添加输入验证:

@dataclass
class Person:
    name: str
    age: float

    def __post_init__(self):
        if type(self.name) is not str:
            raise TypeError("Field 'name' must be of type 'str'.")
        self.age = float(self.age)
        if self.age < 0:
            raise ValueError("Field 'age' cannot be negative.")
Run Code Online (Sandbox Code Playgroud)

这样可以通过以下方式提供良好的输入:

someone = Person(name="John Doe", age=30)
print(someone)

Person(name='John Doe', age=30.0)
Run Code Online (Sandbox Code Playgroud)

尽管所有这些错误的输入都会引发错误:

someone = Person(name=["John Doe"], age=30)
someone = Person(name="John Doe", age="thirty")
someone = Person(name="John Doe", age=-30)
Run Code Online (Sandbox Code Playgroud)

但是,由于数据类是可变的,所以我可以这样做:

someone = Person(name="John Doe", age=30)
someone.age = -30
print(someone)

Person(name='John Doe', age=-30)
Run Code Online (Sandbox Code Playgroud)

从而绕过输入验证。

因此, …

python validation python-dataclasses

4
推荐指数
2
解决办法
773
查看次数

非特定数据类实例的类型提示

我有一个接受any的实例的函数dataclass。什么是合适的类型提示呢?

在python文档中没有找到官方的东西


这是我一直在做的,但我认为这是不对的

from typing import Any, NewType

DataClass = NewType('DataClass', Any)
def foo(obj: DataClass):
    ...
Run Code Online (Sandbox Code Playgroud)

另一个想法是使用Protocol这些类的属性__dataclass_fields____dataclass_params__

python protocols python-3.7 python-dataclasses

4
推荐指数
2
解决办法
510
查看次数

使用python数据类实现多重继承

我正在尝试使用新的 python 数据类来创建一些混合类(在我写这篇文章时,我认为这听起来像是一个轻率的想法),但我遇到了一些问题。看下面的例子:

从数据类导入数据类

@dataclass
class NamedObj:
    name: str

    def __post_init__(self):
        print("NamedObj __post_init__")
        self.name = "Name: " + self.name

@dataclass
class NumberedObj:
    number: int = 0

    def __post_init__(self):
        print("NumberedObj __post_init__")
        self.number += 1

@dataclass
class NamedAndNumbered(NumberedObj, NamedObj):

    def __post_init__(self):
        super().__post_init__()
        print("NamedAndNumbered __post_init__")
Run Code Online (Sandbox Code Playgroud)

如果我再尝试:

nandn = NamedAndNumbered('n_and_n')
print(nandn.name)
print(nandn.number)
Run Code Online (Sandbox Code Playgroud)

我得到

NumberedObj __post_init__
NamedAndNumbered __post_init__
n_and_n
1
Run Code Online (Sandbox Code Playgroud)

暗示它已经运行__post_init__NamedObj,但没有运行NumberedObj。我想要的是让 NamedAndNumbered__post_init__为它的两个混合类 Named 和 Numbered 运行。有人可能认为如果NamedAndNumbered有这样的就可以做到__post_init__

def __post_init__(self):
    super(NamedObj, self).__post_init__()
    super(NumberedObj, self).__post_init__()
    print("NamedAndNumbered …
Run Code Online (Sandbox Code Playgroud)

python multiple-inheritance mixins method-resolution-order python-dataclasses

4
推荐指数
2
解决办法
2267
查看次数

键入:限制为字符串列表

这是 Python 3.7

我有一个这样的数据类:

@dataclass
class Action:
   action: str
Run Code Online (Sandbox Code Playgroud)

但 action 实际上仅限于值“bla”和“foo”。有没有一种明智的方式来表达这一点?

python python-dataclasses python-typing

4
推荐指数
2
解决办法
336
查看次数