标签: python-dataclasses

使用自引用类型提示创建递归数据类

我想用 Python 编写数据类定义,但无法在声明中引用同一类。

我主要想要实现的是这个嵌套结构的类型,如下图所示:

 @dataclass
 class Category:
     title: str
     children: [Category] # I can't refer to a "Category"
  
 tree = Category(title='title 1', children=[
     Category('title 11', children=[]),
     Category('title 12', children=[])
 ])
Run Code Online (Sandbox Code Playgroud)

python type-hinting recursive-datastructures python-dataclasses

25
推荐指数
1
解决办法
7088
查看次数

使Python json编码器支持Python的新数据类

从Python 3.7开始,有一种称为数据类的东西:

from dataclasses import dataclass

@dataclass
class Foo:
    x: str
Run Code Online (Sandbox Code Playgroud)

但是,以下失败:

>>> import json
>>> foo = Foo(x="bar")
>>> json.dumps(foo)
TypeError: Object of type Foo is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

如何将json.dumps()编码实例Foo转换为json 对象

python python-dataclasses

23
推荐指数
7
解决办法
6438
查看次数

如何获得Python 3.7新的数据类字段类型?

Python 3.7引入了称为数据类的新功能.

from dataclasses import dataclass

@dataclass
class MyClass:
    id: int = 0
    name: str = ''
Run Code Online (Sandbox Code Playgroud)

在函数参数中使用类型提示(注释)时,可以使用inspect模块轻松获取带注释的类型.如何获取dataclass字段类型?

python python-dataclasses

20
推荐指数
3
解决办法
8056
查看次数

如何使用数据类创建"仅关键字"字段?

从3.0开始,只支持创建一个参数关键字:

class S3Obj:
    def __init__(self, bucket, key, *, storage_class='Standard'):
        self.bucket = bucket
        self.key = key
        self.storage_class = storage_class
Run Code Online (Sandbox Code Playgroud)

如何使用数据类获得这种签名?像这样的东西,但最好没有SyntaxError:

@dataclass
class S3Obj:
    bucket: str
    key: str
    *
    storage_class: str = 'Standard'
Run Code Online (Sandbox Code Playgroud)

理想情况下是声明性的,但是使用__post_init__钩子和/或替换类装饰器也很好 - 只要代码是可重用的.

编辑:可能是这样的语法,使用省略号文字

@mydataclass
class S3Obj:
    bucket: str
    key: str
    ...
    storage_class: str = 'Standard'
Run Code Online (Sandbox Code Playgroud)

python keyword-argument python-3.7 python-dataclasses

19
推荐指数
2
解决办法
1214
查看次数

数据类与typing.NamedTuple主要用例

长话短说

PEP-557引入了数据类到Python标准库,基本上可以填补因为同样的作用collections.namedtupletyping.NamedTuple.现在我想知道如何分离使用namedtuple仍然是更好的解决方案的用例.

数据类优于NamedTuple

当然,dataclass如果我们需要,所有的功劳都归功于:

  • 可变对象
  • 继承支持
  • property 装饰器,可管理的属性
  • 生成的方法定义开箱即用或可自定义的方法定义

在同一个PEP中简要解释了数据类的优点:为什么不使用namedtuple.

问:在哪些情况下,namedtuple仍然是更好的选择?

但是对于namedtuples这个相反的问题怎么样:为什么不使用dataclass呢?我想从性能的角度来看,名字元组可能更好,但尚未确认.

让我们考虑以下情况:

我们将页面维度存储在一个小容器中,该容器具有静态定义的字段,类型提示和命名访问.不需要进一步散列,比较等.

NamedTuple方法:

from typing import NamedTuple

PageDimensions = NamedTuple("PageDimensions", [('width', int), ('height', int)])
Run Code Online (Sandbox Code Playgroud)

DataClass方法:

from dataclasses import dataclass

@dataclass
class PageDimensions:
    width: int
    height: int
Run Code Online (Sandbox Code Playgroud)

哪种解决方案更可取,为什么?

PS这个问题不是以任何方式重复那个问题,因为我在这里询问是哪个命名元组更好,而不是区别(我在询问之前检查了文档和来源)

python pep namedtuple python-3.7 python-dataclasses

19
推荐指数
6
解决办法
3535
查看次数

验证python数据类中的详细类型

Python 3.7即将到来,我想测试一些奇特的新dataclass+打字功能.使用本机类型和typing模块中的类型,可以很容易地获得正确工作的提示:

>>> import dataclasses
>>> import typing as ty
>>> 
... @dataclasses.dataclass
... class Structure:
...     a_str: str
...     a_str_list: ty.List[str]
...
>>> my_struct = Structure(a_str='test', a_str_list=['t', 'e', 's', 't'])
>>> my_struct.a_str_list[0].  # IDE suggests all the string methods :)
Run Code Online (Sandbox Code Playgroud)

但是我想要尝试的另一件事是在运行时强制类型提示作为条件,即不应该dataclass存在具有不正确类型的类型.它可以很好地实现__post_init__:

>>> @dataclasses.dataclass
... class Structure:
...     a_str: str
...     a_str_list: ty.List[str]
...     
...     def validate(self):
...         ret = True
...         for field_name, field_def in self.__dataclass_fields__.items():
...             actual_type = type(getattr(self, …
Run Code Online (Sandbox Code Playgroud)

python typing python-dataclasses

18
推荐指数
2
解决办法
6707
查看次数

Dataclass:如何创建一个不需要初始化且自动生成的字段?

我使用 field(init= False) 来禁用初始化 self.ref。那么它就是 post 中的一个值。以下代码引发AttributeError: 'Data' object has no attribute 'ref'

from dataclasses import dataclass, field
def make_list(): return [[0] for k in range(9)]
@dataclass
class Data:
    rows: list
    cols: list
    blocks: list
    ref: dict = field(init=False)

    def __init__(self, slots=None):
        self.rows = make_list()
        self.cols = make_list()
        self.blocks = make_list()
        if slots:
            for i in range(9):
                for j in range(9):
                    self.cols[j][i] = self.rows[i][j] = slots[i][j]

    def __post_init__(self):  
          print("post-init executed")
        self.ref = {"rows": self.rows, "cols": self.cols, "blocks": self.blocks}
test …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-dataclasses

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

Python 3.7:Dataclasses和SimpleNameSpace的实用程序

Python 3.7提供了dataclasses具有预定义特殊功能的新功能.

从全局来看,dataclassesSimpleNameSpace都提供了很好的数据封装工厂.

@dataclass
class MyData:
    name:str
    age: int

data_1 = MyData(name = 'JohnDoe' , age = 23)

data_2 = SimpleNameSpace(name = 'JohnDoe' , age = 23)
Run Code Online (Sandbox Code Playgroud)

很多时候我SimpleNameSpace只是用来包装数据并移动它.

我甚至将它子类化为添加特殊功能:

from types import SimpleNameSpace

class NewSimpleNameSpace(SimpleNameSpace):
    def __hash__(self):
        return some_hashing_func(self.__dict__)
Run Code Online (Sandbox Code Playgroud)

对于我的问题:

  1. 有人如何选择SimpleNameSpacedataclasses
  2. 为什么它们是必要的,当扩展时可以达到同样的效果SimpleNameSpace
  3. 所有其他用例dataclasses迎合什么?

python python-3.7 python-dataclasses

17
推荐指数
2
解决办法
1517
查看次数

在 asdict 或序列化中将属性包含在数据类中的推荐方法是什么?

请注意,这类似于如何在 asdict 中获取 @property 方法?

我有一个(冻结的)嵌套数据结构,如下所示。定义了一些(纯粹)依赖于字段的属性。

import copy
import dataclasses
import json
from dataclasses import dataclass

@dataclass(frozen=True)
class Bar:
    x: int
    y: int

    @property
    def z(self):
        return self.x + self.y

@dataclass(frozen=True)
class Foo:
    a: int
    b: Bar

    @property
    def c(self):
        return self.a + self.b.x - self.b.y
Run Code Online (Sandbox Code Playgroud)

我可以按如下方式序列化数据结构:

class CustomEncoder(json.JSONEncoder):
    def default(self, o):
        if dataclasses and dataclasses.is_dataclass(o):
            return dataclasses.asdict(o)
        return json.JSONEncoder.default(self, o)

foo = Foo(1, Bar(2,3))
print(json.dumps(foo, cls=CustomEncoder))

# Outputs {"a": 1, "b": {"x": 2, "y": 3}}
Run Code Online (Sandbox Code Playgroud)

但是,我还想序列化属性 ( …

python serialization immutability python-3.x python-dataclasses

17
推荐指数
3
解决办法
6642
查看次数

在 Dataclass 中创建 DefaultDict 时遇到问题

我在使用新的 defaultdict(dict) 设置简单的数据类时遇到问题。

如果我告诉工厂使用“dict”,如下所示,实例化将失败并出现typerror collection.defaultdict对象不可调用

from collections import defaultdict
from dataclasses import dataclass, field

@dataclass
class ResultSet:
    changed: bool = False
    mqttdata:  defaultdict(dict) = field(default_factory=defaultdict(dict)) # does not work!
Run Code Online (Sandbox Code Playgroud)

它确实使用field(default_factory=defaultdict)工作,但是当我的代码遇到丢失的键时,它会失败 - 大概是因为没有为 dict 设置 defaultdict。

如何在数据类中正确设置新的defaultdict(dict)?

python-3.x defaultdict python-dataclasses

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