我喜欢理解我使用的所有代码,因此当我查看Vector
类here.时,我决定制作一个简化得多的版本,仅执行我认为需要的事情。 (我无法理解该类的__hash__
和__slot__
部分或设置了哈希的位置。
我的精简版本如下:
class vector:
"""Two-dimensional vector."""
def __init__(self, x, y):
"""Initialize vector with coordinates: x, y."""
self.x = x
self.y = y
def copy(self):
"""Return copy of vector."""
# type_self = type(self)
return vector(self.x, self.y)
def move(self, other):
"""Move vector by other (in-place)."""
self.__iadd__(other)
def __eq__(self, other):
"""v.__eq__(w) -> v == w """
if isinstance(other, vector):
return self.x == other.x and self.y == other.y
return NotImplemented
def __iadd__(self, other):
"""v.__iadd__(w) -> v += w
>>> v = vector(1, 2)
>>> w = vector(3, 4)
>>> v += w
>>> v
vector(4, 6)
>>> v += 1
>>> v
vector(5, 7)
"""
if isinstance(other, vector):
self.x += other.x
self.y += other.y
else:
self.x += other
self.y += other
return self
def __repr__(self):
"""v.__repr__() -> repr(v)
>>> v = vector(1, 2)
>>> repr(v)
'vector(1, 2)'
"""
type_self = type(self)
name = type_self.__name__
return "{}({!r}, {!r})".format(name, self.x, self.y)
但是事实证明,我付出了比应有的努力,而当我尝试在下面的代码中使用该类时,我得到TypeError: unhashable type: 'vector'
。
from turtle import *
from random import randint
from utils import square, vector
p1xy = vector(-100, 0)
p1aim = vector(4, 0)
p1body = set()
p2xy = vector(100, 0)
p2aim = vector(-4, 0)
p2body = set()
def inside(head):
"Return True if head inside screen."
return -200 < head.x < 200 and -200 < head.y < 200
def get_best_move_flood_fill(aim):
pass
def draw():
"Advance players and draw game."
p1xy.move(p1aim)
p1head = p1xy.copy()
change = get_best_move_flood_fill(p2aim)
if change == 0:
p2aim.rotate(90)
elif change == 1:
p2aim.rotate(-90)
p2xy.move(p2aim)
p2head = p2xy.copy()
if not inside(p1head) or p1head in p2body:
print('Player blue wins!')
return
if not inside(p2head) or p2head in p1body:
print('Player red wins!')
return
print("xy: ", p1xy)
print("head: ", p1head)
print("Body: ", p1body)
p1body.add(p1head)
p2body.add(p2head)
square(p1xy.x, p1xy.y, 3, 'red')
square(p2xy.x, p2xy.y, 3, 'blue')
update()
ontimer(draw, 200)
setup(420, 420, 370, 0)
hideturtle()
tracer(False)
listen()
onkey(lambda: p1aim.rotate(90), 'a')
onkey(lambda: p1aim.rotate(-90), 'd')
onkey(lambda: p2aim.rotate(90), 'j')
onkey(lambda: p2aim.rotate(-90), 'l')
draw()
done()
有人可以告诉我为避免此错误而进行的最小调整,方法是修改类或使用它的方式?
我已经研究了给定的错误,但无法理解问题所在。可能是使用set()
,但如果我不使用集合,则会有重复的元素。
答案 0 :(得分:2)
问题是您的__eq__
的{{1}}方法。定义该方法后,默认的vector
by address方法将不再可用。您需要删除__hash__
或定义__eq__
,以使相等的向量也一样哈希。
还要注意,turtle本身定义了一个最小的__hash__
类,您可能会发现它直接或作为您的Vec2D
类的基类有用。