Если вы хотите, чтобы хэш-класс Point
работал без особой работы, кортеж подкласса и добавьте свои собственные методы соседей.
class Point(tuple):
def r_neighbor(self):
return Point((self[0] + 1, self[1]))
def l_neighbor(self):
[...]
x = Point((10, 11))
print x
print x.r_neighbor()
Конструктор кортежей хочет итерацию, поэтому двойные парены в Point((10, 11))
;если вы хотите избежать этого, вы всегда можете переопределить __new__
(переопределение __init__
бессмысленно, потому что кортежи неизменны):
def __new__(self, x, y):
return super(Point, self).__new__(self, (x, y))
Это также может быть место для применения модульной арифметики - хотя этодействительно будет зависеть от того, что вы делаете:
def __new__(self, x, y, gridsize=100):
return super(Point, self).__new__(self, (x % gridsize, y % gridsize))
или от включения сеток произвольных измерений, и вернитесь к использованию кортежей в __new__
:
def __new__(self, tup, gridsize=100):
return super(Point, self).__new__(self, (x % gridsize for x in tup))
Относительно вашего вопроса о ресурсах: поскольку Point
является неизменным классом, он плохо подходит для хранения информации о ресурсах, которые могут измениться.Дефолдикт был бы удобен;Вы не должны были бы инициализировать это.
from collections import defaultdict
grid = defaultdict(list)
p = Point((10, 13))
grid[(10, 13)] = [2, 3, 4]
print grid[p] # prints [2, 3, 4]
print grid[p.r_neighbor] # no KeyError; prints []
Если вы хотите большей гибкости, вы можете использовать dict вместо списка в defaultdict;но defaultdict(defaultdict)
не сработает;Вы должны создать новую фабричную функцию defaultdict.
def intdict():
return defaultdict(int)
grid = defaultdict(intdict)
или более кратко
grid = defaultdict(lambda: defaultdict(int))
затем
p = Point((10, 13))
grid[(10, 13)]["coins"] = 50
print grid[p]["coins"] # prints 50
print grid[p.r_neighbor]["coins"] # prints 0; again, no KeyError