标签: python-dataclasses

我可以为数据类的子类提供默认值吗?

我想创建一个类层次结构,其中类的所有对象Base都有一个字段field1,但不同的子类有不同的默认值field1。这些类是数据持有者,因此dataclasses看起来是一个完美的库。

考虑以下 python 3.7+ 代码。

from dataclasses import dataclass, field
from typing import Any, Iterable

@dataclass
class Base:
    field1: Iterable[Any]

@dataclass
class Sub(Base):
    field2: Any
    field1: Iterable[Any] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)

代码失败,给了我TypeError: non-default argument 'field2' follows default argument. 这有点令人惊讶,因为遵循超类的field2非默认参数,而该类的默认参数实际上位于.field1field1Subfield2

根据有关数据类继承的文档中的示例,子类中的字段会覆盖超类中的字段,但保留字段顺序。所以这个错误是有道理的。

这里有任何合适的解决方法,还是我必须手动实现所有内容?

python python-dataclasses

7
推荐指数
1
解决办法
1700
查看次数

Python 数据类 AttributeError

我有一个这样设置的数据类:

from dataclasses import dataclass, field
from typing import List

@dataclass
class stats:
    target_list: List[None] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)

当我尝试像这样比较列表的内容时:

if stats.target_list == None:
    pass
Run Code Online (Sandbox Code Playgroud)

我得到 AttributeError: type object 'stats' has no attribute 'target_list'

我该如何解决这个问题?谢谢

python python-dataclasses

7
推荐指数
1
解决办法
7235
查看次数

Python 类型注释会减慢代码速度

我正在优化我的代码以提高性能,当我用来cProfile检查我的代码时,大量的运行时间是由于类型注释造成的!删除类型注释确实可以提高性能。cProfiler您可以在下面看到带注释和不带注释的输出。

注释代码: 带注释的代码性能

未注释的代码: 没有注释的代码的性能

带注释的明显使用了__call____new__inner__getitem____hash__等方法typing.py,而且比不带注释的慢了一倍!

我的测试代码很简单:

from reil.datatypes import reildata

x = reildata.Categorical(name='cat', categories=('A', 'B', 'C', 'D', 'E'))

for _ in range(10000):
    [x(v) for v in ('A', 'B', 'C', 'D', 'E')]
Run Code Online (Sandbox Code Playgroud)

这是主代码的相关部分(datatypes.reildata.py):

from __future__ import annotations

import dataclasses
import itertools
from dataclasses import field
from typing import Any, Callable, Dict, Generic, Iterable, Iterator, List, Optional, Sequence, Tuple, TypeVar, Union, cast

from typing_extensions import …
Run Code Online (Sandbox Code Playgroud)

type-hinting cprofile python-3.x python-dataclasses

7
推荐指数
0
解决办法
737
查看次数

以编程方式扩展数据类' __repr__

假设我有一个带有 set 方法的数据类。如何扩展 repr 方法,以便在调用 set 方法时它也会更新:

from dataclasses import dataclass
@dataclass
class State:
    A: int = 1
    B: int = 2
    def set(self, var, val):
        setattr(self, var, val)
Run Code Online (Sandbox Code Playgroud)

前任:

In [2]: x = State()

In [3]: x
Out[3]: State(A=1, B=2)

In [4]: x.set("C", 3)

In [5]: x
Out[5]: State(A=1, B=2)

In [6]: x.C
Out[6]: 3
Run Code Online (Sandbox Code Playgroud)

我想要的结果

In [7]: x
Out[7]: State(A=1, B=2, C=3)
Run Code Online (Sandbox Code Playgroud)

python python-dataclasses

7
推荐指数
1
解决办法
8573
查看次数

如何将 json 文件转换为 python 类?

h.json考虑这个名为“我想将其转换为 python 数据类”的 json 文件。

{
    "acc1":{
        "email":"acc1@example.com",
        "password":"acc1",
        "name":"ACC1",
        "salary":1
    },
    "acc2":{
        "email":"acc2@example.com",
        "password":"acc2",
        "name":"ACC2",
        "salary":2
    }

}
Run Code Online (Sandbox Code Playgroud)

我可以使用替代构造函数来获取每个帐户,例如:

import json
from dataclasses import dataclass

@dataclass
class Account(object):
    email:str
    password:str
    name:str
    salary:int
    
    @classmethod
    def from_json(cls, json_key):
        file = json.load(open("h.json"))
        return cls(**file[json_key])
Run Code Online (Sandbox Code Playgroud)

但这仅限于数据类中定义的参数(电子邮件、姓名等)。

如果我要修改 json 以包含其他内容(例如年龄)怎么办?该脚本最终将返回一个TypeError,特别是TypeError: __init__() got an unexpected keyword argument 'age'.

有没有办法根据dict(json对象)的键动态调整类属性,这样我就不必每次向json添加新键时都添加属性?

python oop json python-dataclasses python-class

7
推荐指数
2
解决办法
2万
查看次数

具有数据类属性的必需位置参数

似乎已经对此进行了相当多的讨论。我发现这篇文章特别有帮助,它似乎提供了最好的解决方案之一。

但推荐的解决方案存在问题。

嗯,一开始看起来效果很好。考虑一个没有属性的简单测试用例:

@dataclass
class Foo:
    x: int
Run Code Online (Sandbox Code Playgroud)
>>> # Instantiate the class
>>> f = Foo(2)
>>> # Nice, it works!
>>> f.x
2
Run Code Online (Sandbox Code Playgroud)

x现在尝试使用推荐的解决方案作为属性来实现:

@dataclass
class Foo:
    x: int
    _x: int = field(init=False, repr=False)
    
    @property
    def x(self):
        return self._x
    
    @x.setter
    def x(self, value):
        self._x = value
Run Code Online (Sandbox Code Playgroud)
>>> # Instantiate while explicitly passing `x`
>>> f = Foo(2)
>>> # Still appears to work
>>> f.x
2
Run Code Online (Sandbox Code Playgroud)

可是等等...

>>> # Instantiate without any arguments
>>> f …
Run Code Online (Sandbox Code Playgroud)

python properties python-dataclasses

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

如何在没有第三方库的情况下将 JSON 对象解析为 python 数据类?

我想解析 json 并将其保存在数据类中以模拟 DTO。目前,我必须手动将所有 json 字段传递给数据类。我想知道有没有一种方法可以通过添加 json 解析的字典来做到这一点。“dejlog”到数据类,所有字段都会自动填充。

from dataclasses import dataclass,  asdict


@dataclass
class Dejlog(Dataclass):
    PK: str
    SK: str
    eventtype: str
    result: str
    type: str
    status: str

def lambda_handler(event, context):
    try:
        dejlog = json.loads(event['body'])

        x = Dejlog(dejlog['PK'])

        print(x)

        print(x.PK)
Run Code Online (Sandbox Code Playgroud)

python json python-dataclasses

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

从 python `dataclass` `__repr__` 中排除默认字段

概括

我有dataclass10多个字段print()使用它们将有趣的上下文埋藏在默认值的墙中 - 让我们通过不再不必要地重复这些来使它们变得更友好。

Python 中的数据类

Python 的@dataclasses.dataclass()( PEP 557 ) 提供自动可打印表示 ( __repr__())。

假设这个例子,基于 python.org 的

from dataclasses import dataclass


@dataclass
class InventoryItem:
    name: str
    unit_price: float = 1.00
    quantity_on_hand: int = 0
Run Code Online (Sandbox Code Playgroud)

装饰器@dataclass(repr=True)(默认)将得到print()一个很好的输出:

InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)
Run Code Online (Sandbox Code Playgroud)

我想要的:跳过打印默认值

repr它会打印所有字段,包括您不想显示的隐含默认值。

print(InventoryItem("Apple"))

# Outputs: InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)
# I want: InventoryItem(name='Apple')
Run Code Online (Sandbox Code Playgroud)
print(InventoryItem("Apple", unit_price="1.05"))

# Outputs: InventoryItem(name='Apple', unit_price='1.05', quantity_on_hand=0)
# I want: InventoryItem(name='Apple', unit_price='1.05') …
Run Code Online (Sandbox Code Playgroud)

python repr python-dataclasses

7
推荐指数
1
解决办法
3819
查看次数

Python获取数据类中所有字段的名称

我正在尝试编写一个函数来记录数据类,我想获取数据类中所有字段的名称并将值打印到每个字段(类似于编写一个函数来打印字典)

IE

@dataclasses.dataclass
class Test:
    a: str = "a value"
    b: str = "b value"


test = Test()
def print_data_class(dataclass_instance):
   fields = # get dataclass fileds
   for field in fields:
       print(f{field}: {dataclass.field})
print_data_class(test)

-->
"a"  : "a value"
"b"  : "b value"
Run Code Online (Sandbox Code Playgroud)

但是我一直无法找到如何获取数据类的字段,有谁知道如何做到这一点?

谢谢

python python-dataclasses python-3.9

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

初始化Python数据类对象而不传递实例变量或默认值

我想初始化 python 数据类对象,即使没有实例变量传递给它并且我们没有向参数添加默认值

@dataclass
class TestClass:
   
   paramA: str
   paramB: float
   paramC: str

obj1 = TestClass(paramA="something", paramB=12.3)

Run Code Online (Sandbox Code Playgroud)

这里它不允许我创建对象并且它会抛出

TypeError: __init__() missing 1 required positional argument: 'paramC'
Run Code Online (Sandbox Code Playgroud)

我可以使用默认值来解决此错误。

paramC: str = None
# OR
paramC: str = ""
Run Code Online (Sandbox Code Playgroud)

但我不想使用 paramC 的默认值,因为我想要一个场景,如果我们传递 paramC 那么只有它应该存在于对象中,否则它不应该存在。因此,如果我们在这里使用默认值,paramC 将始终存在于对象中,其值为None或空字符串。

如果在初始化期间未传递参数,我想跳过参数的初始化。

python python-3.x python-dataclasses

6
推荐指数
1
解决办法
6668
查看次数