标签: python-dataclasses

如何使__slots__更好地使用数据类?

决定除去直接支持__slots__从数据类为Python 3.7。

尽管如此,__slots__仍可以与数据类一起使用:

from dataclasses import dataclass

@dataclass
class C():
    __slots__ = "x"
    x: int
Run Code Online (Sandbox Code Playgroud)

但是,由于这种方式__slots__有效,因此无法为数据类字段分配默认值:

from dataclasses import dataclass

@dataclass
class C():
    __slots__ = "x"
    x: int = 1
Run Code Online (Sandbox Code Playgroud)

这会导致错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 'x' in __slots__ conflicts with class variable
Run Code Online (Sandbox Code Playgroud)

如何__slots__与默认dataclass字段一起使用?

python slots python-3.x python-dataclasses

8
推荐指数
5
解决办法
2094
查看次数

Python 数据类:如果 __post_init__ 执行类型转换,要使用什么类型?

我有一个 Python 类,它的字段可以传递几种序列类型之一。为了简化,我将坚持使用元组和列表。__init__将参数转换为MyList.

from typing import Union
from dataclasses import dataclass, InitVar, field

class MyList(list):
    pass

@dataclass
class Struct:
    field: Union[tuple, list, MyList]

    def __post_init__(self):
        self.field = MyList(self.field)
Run Code Online (Sandbox Code Playgroud)

我应该使用什么类型的field声明?

  • 如果我提供所有可能输入类型的联合,则代码不会记录访问field始终为 a 的内容。MyList
  • 如果我只提供了最后的MyList类型,PyCharm当我通过抱怨Struct()一个list

我可以改为使用:

_field: InitVar[Union[tuple, list, MyList]] = None
field: MyList = field(init=False)

def __post_init__(self, _field):
    self.field = MyList(_field)
Run Code Online (Sandbox Code Playgroud)

但这非常难看,尤其是在 3 个字段中重复时。此外,我必须构造一个类似的结构Struct(_field=field)而不是Struct(field=field).

2018 年 4 月,《tm》在 PyCharm 的公告中对这个问题进行了评论: …

python python-dataclasses

8
推荐指数
2
解决办法
1212
查看次数

如何显示使用@dataclass类装饰器时生成的代码?

Python 3.7引入了dataclasses包含@dataclass装饰器的模块。该装饰器可以生成类函数。如何打印这些生成的函数?

python python-3.7 python-dataclasses

8
推荐指数
2
解决办法
160
查看次数

如何忽略传递给数据类的额外参数?

我想创建一个config dataclass,以简化对特定环境变量的白名单和访问(os.environ['VAR_NAME']相对于而言,输入代码很麻烦config.VAR_NAME)。因此,我需要无视我的未使用的环境变量dataclass__init__函数,但我不知道如何提取默认__init__为了与例如,一个函数,还包括将其包装*_为一体的论据之一。

import os
from dataclasses import dataclass

@dataclass
class Config:
    VAR_NAME_1: str
    VAR_NAME_2: str

config = Config(**os.environ)
Run Code Online (Sandbox Code Playgroud)

运行这个给了我TypeError: __init__() got an unexpected keyword argument 'SOME_DEFAULT_ENV_VAR'

python python-3.x python-dataclasses

8
推荐指数
3
解决办法
962
查看次数

数据类:需要在模型字段分组中至少设置一个值

如何要求数据类上的一组字段中的至少一个字段设置为真值?这是否需要自定义根验证器方法,因为它需要一次查看许多字段?例如,考虑以下数据类:

@dataclass
class MyModel:
    field1: Optional[str]: None
    field2: Optional[str]: None
    field3: Optional[str]: None
Run Code Online (Sandbox Code Playgroud)

如何要求这三个字段(field1field2field3)中的至少一个设置为非空字符串?是否有某种内置方法可以指定至少一个字段必须为非零/空(除了自定义根验证器之外)?

python python-3.7 python-dataclasses python-typing pydantic

8
推荐指数
2
解决办法
4577
查看次数

错误:不可散列的类型:带有@dataclass的'dict'

我有一个班级表:

@dataclass(frozen=True, eq=True)
class Table:
    name: str
    signature: Dict[str, Type[DBType]]
    prinmary_key: str
    foreign_keys: Dict[str, Type[ForeignKey]]
    indexed: List[str]
Run Code Online (Sandbox Code Playgroud)

并需要创建这样的字典:


table = Table(*args)
{table: 'id'}
Run Code Online (Sandbox Code Playgroud)

类型错误:不可散列的类型:'dict'

不明白有什么问题。

python hashtable python-dataclasses

8
推荐指数
1
解决办法
5398
查看次数

Python 冻结数据类,允许通过方法更改属性

假设我有一个数据类:

@dataclass(frozen=True)
class Foo:
    id: str
    name: str
Run Code Online (Sandbox Code Playgroud)

我希望它是不可变的(因此是frozen=True),这样foo.id = bar就会foo.name = baz失败。但是,我希望能够删除 id,如下所示:

foo = Foo(id=10, name="spam")

foo.strip_id()
foo
-> Foo(id=None, name="spam")
Run Code Online (Sandbox Code Playgroud)

我尝试了一些方法,覆盖setattr,但没有任何效果。有一个优雅的解决方案吗?(我知道我可以编写一个方法,返回一个新的冻结实例,该实例是相同的,只是该 id 已被删除,但这似乎有点 hacky,并且它需要我这样做foo = foo.strip_id(),因为foo.strip_id()实际上不会改变foo

编辑:

尽管一些评论者似乎不同意,但我认为“完全可变,用它做你想做的事”和“不可变,除非以这种特殊的、严格控制的方式”之间存在合理的区别

python python-dataclasses

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

如何声明Python数据类成员字段与数据类类型相同

如何让数据类的成员字段与 python3.7+ 中的类名相同?我正在尝试定义一个像这样的类(可以用 Java 或 C++ 完成)——它可以用作 LinkedList 节点的类

@dataclass
class Node:
  val:str
  next:Node
  prev:Node
Run Code Online (Sandbox Code Playgroud)

然而,我得到的只是NameError: name 'Node' is not defined。在数据类中拥有自引用成员变量的正确方法应该是什么

python python-3.x python-dataclasses

8
推荐指数
2
解决办法
2255
查看次数

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
查看次数