我遇到一种情况,我需要将变量 a、b 和 c 一起存储在数据类中,其中c = f(a,b)a、b 可以发生变化。c打印对象时,I 需要与 a 和 b 一起显示,并且c只能通过更改a或来更改b。我认为做到这一点的最好方法就是c通过财产创造价值。
我尝试使用的最小示例:
@dataclass
class Demo:
a:int
b:int
c:int = field(init=False)
@property
def c(self) -> int:
return self.a * self.b
Run Code Online (Sandbox Code Playgroud)
但是,调用此结果会导致AttributeError: can't set attribute. 我怀疑代码试图将 c 设置为field(init=False),但失败了,因为 c 没有设置器。
我考虑过的选项(不包括我尝试过的使代码以不同方式崩溃的替代方案):
c在 init 中
@c.setter什么都不做的
sys._getframe().f_back.f_code则在 setter 中使用会引发错误__init__dataclasses_json is a library that provides JSON capabilities to python's data classes. I noticed that overriding to_dict method has no effect. Here's an example:
@dataclass_json
@dataclass
class Message2:
message: str
weight: int
def to_dict(self, encode_json=False):
print('Custom to_dict')
ret = {'MESSAGE': self.message, 'WEIGHT': self.weight}
return ret
m2 = Message2('m2', 2)
print(m2.to_dict())
Run Code Online (Sandbox Code Playgroud)
The code prints the following:
{'message': 'm2', 'weight': 2}
While I was expecting
Custom to_dict
{'MESSAGE': 'm2', 'WEIGHT': 2}
Run Code Online (Sandbox Code Playgroud)
If I remove the @dataclass_json line, I get the desired output. …
我有一个根级config类,我通过依赖注入在我的代码库中传递它。
问题是,我有这个数据类,需要此配置中的一些属性来world_coords计算__post_init__().
为了保持测试干净并避免其他测试导入问题(此处未讨论),我希望能够将配置直接传递给此对象,而不是从导入中读取这些值。然而,如果我将配置构建为参数,它就会成为数据类的一个属性,这是我试图避免的。实际上不需要RoadSegmentNode保留使用过的配置的引用。
这是该类的基本结构:
@dataclass(eq=True, frozen=True) # make hashable
class RoadSegmentNode:
tile_index: Tuple[int, int] # (r, c)
dir: Direction
node_type: RoadNodeType
world_coords: Tuple[int, int] = field(init=False)
def __post_init__(self):
# (Use config variables here, e.g. `config.TILE_WIDTH`, to calculate x and y)
# Hack to get around frozen=True. We don't care that we're mutating
# an "immutable" object on __init__().
object.__setattr__(self, "world_coords", (x, y))
Run Code Online (Sandbox Code Playgroud)
这是我为了保持依赖注入模型而采取的权宜之计,以暂时解除我的测试障碍。请注意RoadSegmentNode现在有一堆仅用于初始化的新属性。这比保留对配置的引用要好一点,因为至少它们是明确的,但它仍然是一个相当糟糕的设计。
@dataclass(eq=True, frozen=True) # make hashable
class RoadSegmentNode: …Run Code Online (Sandbox Code Playgroud) kwargs我可以在创建数据类对象时使用,没有问题:
@dataclass()
class Data:
name: str = 'Unnamed'
additional: int = None
things: int = None
dic = {'additional': 123, 'things': 456}
res = Data(name='Somename', **dic)
Run Code Online (Sandbox Code Playgroud)
Output: Data(name='Somename', additional=123, things=456)
Run Code Online (Sandbox Code Playgroud)
kwargs但是,当数据类不属于调用参数时,我想将其解包:
@dataclass()
class Data:
name: str = 'Unnamed'
additional: int = None
things: int = None
def __post_init__(self):
self(**dic) #unpack kwargs to fields
dic = {'additional': 123, 'things': 456}
res = Data(name='Somename')
Run Code Online (Sandbox Code Playgroud) 如果我执行以下命令:
@dataclass
class Test:
hi: Optional[str] = field(
default_factory=lambda: str(uuid.uuid1()))
@dataclass
class Test2:
hi: Optional[str] = str(uuid.uuid1())
if __name__ == "__main__":
a = Test() # Test(hi='115a865c-33be-11eb-94a1-34c93db23648')
b = Test() # Test(hi='115a865d-33be-11eb-8c6f-34c93db23648')
c = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
d = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
Run Code Online (Sandbox Code Playgroud)
为什么Test会为每个实例返回不同的 uuid,而Test2每次都会返回相同的 uuid?
另外,为什么default factory需要而不需要default?
我正在做一个项目来了解有关使用 Python 的更多信息dataclasses。具体来说,我试图将 API 响应表示为一个dataclass对象。但是,由于 API 响应的结构,我遇到了一个问题。
以下是 API 的响应示例:
{
"@identifier": "example",
"@name": "John Doe",
}
Run Code Online (Sandbox Code Playgroud)
有些字段的名称中包含特殊字符。这意味着我无法直接映射 my 的属性dataclass,因为@属性名称中不允许使用特殊字符 ( SyntaxError)。
有没有办法为我的属性定义别名dataclass,以便我可以将 API 响应直接映射到dataclass对象?或者是否有必要先清理响应?
下面的代码有效,但我收到 PyCharm 的以下警告:
在“(...) -> Any”中找不到参考
__annotations__。
我想这是因为我正在使用Callable. 我没有找到类似的东西Dataclass。我应该使用哪种类型?
from __future__ import annotations
from dataclasses import dataclass
from typing import Callable
@dataclass
class Fruit:
color: str
taste: str
def get_cls() -> Callable:
return Fruit
attrs = get_cls().__annotations__ # <- IDE warning
print(attrs)
Run Code Online (Sandbox Code Playgroud) 我对这种行为感到困惑:我有一个冻结的数据类,其中只需要 10 个,所以我想将它们放入枚举中,并且成功了。后来,我意识到我希望能够为它们命名,突然间,枚举无法实例化数据类。
import enum
import dataclasses as dc
class Stats(int, enum.Enum):
HP = 0
STA = 1
SPD = 2
ATK = 3
DEF = 4
SPATK = 5
SPDEF = 6
@dc.dataclass(frozen=True)
class Strand:
keeps: tuple[Stats, ...]
costs: int
class Strands(Strand, enum.Enum):
VIT = ((Stats.HP,), 1000)
END = ((Stats.STA,), 1000)
LTH = ((Stats.SPD,), 1000)
AGG = ((Stats.ATK,), 1000)
HRD = ((Stats.DEF,), 1000)
GFT = ((Stats.SPATK,), 1000)
DOM = ((Stats.SPDEF,), 1000)
VIGOR = ((Stats.HP, Stats.STA), 5000)
MIGHT = ((Stats.ATK, …Run Code Online (Sandbox Code Playgroud) 您好,有人可以解释一下这里发生的事情:我想用随机值实例化对象。
@dataclass
class Particle:
pos = (random.randint(0, 800), random.randint(0, 800))
for _ in range(3):
p = Particle()
print(p.pos)
Run Code Online (Sandbox Code Playgroud)
印刷:
预期的行为将是具有不同值的三个元组。这里发生了什么事??
(当我使用普通类时,它按预期工作)
什么之间的区别@dataclass(frozen=True)和@dataclass(frozen=False)?我什么时候应该使用哪个?