Spw*_*ack 0 python python-dataclasses
from dataclasses import dataclass
@dataclass
class coordinate:
x: int
y: int
objects = {}
pos = coordinate(0, 0)
objects[pos] = "A"
pos.x += 1 # Changing the current position I am looking at
objects[pos] = "B"
pos.y += 1
objects[pos] = "C"
for position in objects:
print(position, objects[position])
Run Code Online (Sandbox Code Playgroud)
这会抛出TypeError: unhashable type: 'coordinate'.
设置@dataclass(frozen=True, eq=True)投掷dataclasses.FrozenInstanceError: cannot assign to field 'x'。
最后,使用@dataclass(unsafe_hash=True)结果:
coordinate(x=1, y=1) C
coordinate(x=1, y=1) C
coordinate(x=1, y=1) C
Run Code Online (Sandbox Code Playgroud)
实现此目的的一种方法是使用objects[(pos.x, pos.y)],但这似乎违背了使用数据类的初衷。有没有更好、更Pythonic的方法来做到这一点?
dict键应该是不可变的对象,因此frozen=True是不可协商的。
要“修改”冻结对象,您需要复制它。该dataclasses模块为此提供了一个便利的功能,replace.
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class coordinate:
x: int
y: int
objects = {}
pos = coordinate(0, 0)
objects[pos] = "A"
pos = replace(pos, x=pos.x+1) # Changing the current position I am looking at
objects[pos] = "B"
pos = replace(pos, y=pos.y+1)
objects[pos] = "C"
for position in objects:
print(position, objects[position])
Run Code Online (Sandbox Code Playgroud)