标签: python-dataclasses

在python数据类__init__方法中强制进行类型转换

我有以下非常简单的数据类:

import dataclasses

@dataclasses.dataclass
class Test:
    value: int
Run Code Online (Sandbox Code Playgroud)

我创建了该类的实例,但我使用了一个字符串而不是整数:

>>> test = Test('1')
>>> type(test.value)
<class 'str'>
Run Code Online (Sandbox Code Playgroud)

我真正想要的是强制转换为我在类定义中定义的数据类型:

>>> test = Test('1')
>>> type(test.value)
<class 'int'>
Run Code Online (Sandbox Code Playgroud)

我必须__init__手动编写该方法还是有一种简单的方法来实现此目的?

python python-dataclasses

7
推荐指数
4
解决办法
867
查看次数

cython 是否支持数据类或类似的东西

我对在 Python 和 Cython 代码之间传递数据很感兴趣,以便可以从 C 访问数据而无需 GIL。我正在考虑使用数据类(自 py3.7 起)、命名元组(自 py3.6 起具有很好的定义语法)或 Cython 的扩展类型(cdef classess)来实现这一点。

不幸的是,数据类和命名元组似乎像来自 Cython 的通用对象一样被处理,而没有任何编译成 C 的支持。

可以使用 Cython 扩展类型(cdef 类),但与数据类相比,它们有许多缺点,最重要的是,您必须__init__使用样板代码来实现以设置所有类属性,对吗?

python cython namedtuple python-3.7 python-dataclasses

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

通过普通类、数据类和命名元组创建对象的有趣性能

我正在浏览数据类并命名元组。我发现这种行为在使用 python 的不同特性创建对象时具有不同的性能。

数据类

In [1]: from dataclasses import dataclass
   ...:
   ...: @dataclass
   ...: class Position:
   ...:     lon: float = 0.0
   ...:     lat: float = 0.0
   ...:

In [2]: %timeit for _ in range(1000): Position(12.5, 345)
326 µs ± 34.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Run Code Online (Sandbox Code Playgroud)

普通班:

In [1]: class Position:
   ...:
   ...:     def __init__(self, lon=0.0, lat=0.0):
   ...:         self.lon = lon
   ...:         self.lat = lat
   ...:

In [2]: %timeit for _ in range(1000): …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-internals python-performance python-dataclasses

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

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

我想创建一个类层次结构,其中类的所有对象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万
查看次数