У меня есть этот код, который находит кратчайший и самый быстрый путь между источником и пунктом назначения.
class Node(object):
def __init__(self, ID, name, power, generation):
"""
Creates Node Object
Requires: (id = int), (name = string), (power = int), (generation = int)
"""
self.id = ID
self.name = name
self.power = power
self.generation = generation
def getId(self):
"""
Gets id atribute.
"""
return self.id
def getName(self):
"""
Get name atribute.
"""
return self.name
def getPower(self):
"""
Get power atribute.
"""
return self.power
def getGeneration(self):
"""
Get generation atribute.
"""
return self.generation
def allInfo(self):
'''
Gives a representation of each node atribiutes
'''
return "ID: " + str(self.id) + " | NAME: " + self.name + " | POWER: " + str(self.power) + " | GENERATION: " + str(self.generation)
def __str__(self):
return self.name
def __eq__(self, other):
'''
Sets node if equal to other id if is an instance
'''
if isinstance(other, Node):
return self.id == other.id
return False```
класс Диграф (объект):
def __init__(self):
"""
Nodes is a list of the nodes in the graph.
Edges is a dict mapping each node to a list of its children.
"""
self.nodes = []
self.edges = {}
def addNode(self, node):
"""
Adds the nodes.
"""
if node in self.nodes:
raise ValueError('Duplicate node')
else:
self.nodes.append(node)
self.edges[node] = []
деф основной (аргументы): ''' Основная функция, которая получает аргументы в виде файлов, заданных в оболочке, для запуска программы. Требует: args является старым для нескольких файлов, заданных для чтения Гарантирует: Создает выходной файл со временными соединениями станций '''
stations = []
conns = []
file_in = open(args[1], "r")
for line in file_in:
if (line[0] != "#"):
station_info = line.split(", ")
stations.append(Node(int(station_info[0]),
station_info[1],
int(station_info[2]),
int(station_info[3])))
conns.append(line.split("(")[1].split(", "))
g = Digraph()
for station in stations:
g.addNode(station)
aux = 0
for station in stations:
for s in conns[aux]:
# por \r\n em mac
pos = (int(s.replace("\n", ""))) - 1
g.addEdge(Edge(station, stations[int(pos)]))
aux += 1
file_in.close()
file_in = open(args[2], "r")
maxTest = len(file_in.readlines())
file_in.close()
file_in = open(args[2], "r")
file_out = open(args[3], "w")
count = 0
for line in file_in:
line = line.replace("\n", "")
stationNames = line.split(" ")
stop = False
stationA = findStation(stations, stationNames[0])
if stationA == None:
file_out.write(stationNames[0] + " out of the network\n")
stop = True
stationB = findStation(stations, stationNames[1])
if stationB == None:
file_out.write(stationNames[1] + " out of the network\n")
stop = True
if stationA == stationB:
file_out.write("Trying to connect same station (" + stationA.getName() + ", " + stationB.getName() + ")\n")
stop = True
if not stop:
file_out.write(str(search(g, stationA, stationB)) + "\n")
count += 1
percentage = round(count * 100 / maxTest, 1)
sys.stdout.write("\r Progress: " + str(percentage) + "% | ")
sys.stdout.write("Tested: " + str(count) + " of " + str(maxTest) + " connections!")
sys.stdout.flush()
sys.stdout.write("\n")
file_in.close()
file_out.close()
but i'm getting this error
C:\Users\André Ramos\Desktop\Project\Project\relayStationsGroup12>python
relayStations.py inputFile1.txt inputFile2.txt out.txt
########################## Relay Stations ############################
RelayStations is running...
Traceback (most recent call last):
File "relayStations.py", line 339, in <module>
main(sys.argv)
File "relayStations.py", line 270, in main
g.addNode(station)
File "relayStations.py", line 113, in addNode
self.edges[node] = ()
TypeError: unhashable type: 'Node'
Ваши узлы являются экземплярами пользовательского класса Node
:
Node(int(station_info[0]),
station_info[1],
int(station_info[2]),
int(station_info[3]))
Но Python словари требует, чтобы их ключи были хешируемый:
An object is hashable if it has a hash value which never changes during its lifetime (it needs a
__hash__()
method), and can be compared to other objects (it needs an__eq__()
method). Hashable objects which compare equal must have the same hash value.Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
All of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id().
Поэтому, если вы хотите использовать свои узлы в качестве ключей словаря, вы должны реализовать для них магические методы __hash__
и __eq__
.
Но у меня есть метод экв.
Вам нужен не только __eq__
метод, но и __hash__
.
Ошибка, кажется, добавляется в код, который вы здесь не показали, в
relayStations.py
строке 113. Я боюсь, что ошибка явная и что вы пытаетесь использовать изменяемый тип в качестве ключа в словаре. Вы должны показать классNode
, если вам нужна дополнительная помощь.