ID incremento automatico per le istanze di classe
-
25-10-2019 - |
Domanda
responsabilità : si tratta di un progetto semestre che sto attualmente lavorando. La mia domanda è per quanto riguarda un dettaglio livello di implementazione e non fa parte dello schema di classificazione. Sto scrivendo questo codice come un modo per testare la teoria che propongo per la carta che scriverò.
Inoltre, ho considerato le risposte per questa domanda con poca fortuna, quindi per favore non considerare questo come un duplicato di tale questione
Il problema :
Ho un grafico (G = (V, E)). Ad un certo punto il mio algoritmo, ho bisogno di trasformare questo in un ipergrafo (in un certo senso) da "collasso" più nodi (diciamo, v_1, v_2, ..., v_n
) in un nodo (diciamo, v
). Nel contesto del problema, ciò implica che devo cambiare i bordi E
tale che qualsiasi e
bordo tra qualsiasi v_1, v_2, v_n
e qualsiasi altro u
nodo V
verrà modificato tale che e
è ora tra u
e v
.
Per cattura che ci possono ora esistere più bordi distinti tra ogni coppia di nodi, ho bisogno di fare un identificatore unico per ciascun bordo. Ho cercato di fare questo per mezzo di e ID, che sono attualmente in grado di applicare correttamente.
Questo è quello che ho provato :
class Edge:
_ID = 0
def __init__(self, u, v, w, c,f=0):
self.id = Edge._ID
Edge._ID += 1
self.src = u
self.dest = v
self.weight = w
self.capacity = c
self.flow = f
Tuttavia, quando cerco di istanziare un nuovo bordo, ottengo il seguente errore:
>>> e = Edge(1,3,5,10,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "UnsplittableFlow.py", line 14, in __init__
self.id = Edge._ID; Edge._ID += 1
UnboundLocalError: local variable '_ID' referenced before assignment
Modifica :
Con i consigli di alcune risposte, sono stato in grado di correggere l'errore di un'istanza-tempo. Tuttavia, un altro errore persiste. Ecco il mio codice e gli errori:
class Edge:
_ID = 0
def __init__(self, u, v, w, c,f=0):
self.id = self._ID; self._ID += 1
self.src = u
self.dest = v
self.weight = w
self.capacity = c
self.flow = f
Errore:
>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
0
>>> f = Edge(2,3,5,10,0)
>>> f.id
0
>>> Edge._ID
0
Apprezzerei tutto l'aiuto
Grazie
Soluzione
È comunque possibile utilizzare self
per arrivare al _ID
.
self.id = self._ID
self.__class__._ID += 1
Se stai usando CPython, si può avere ID di un uomo pigro:
class Edge(object):
@property
def id(self): return id(self)
Altri suggerimenti
Il codice modificato è trattare _ID
come se si trattasse di una variabile di istanza, non è una variabile di classe. Sulla base di risposta di Matt Joiner quello che penso vuoi dire è questo:
class Edge:
_ID = 0
def __init__(self, u, v, w, c,f=0):
self.id = self._ID; self.__class__._ID += 1
self.src = u
self.dest = v
self.weight = w
self.capacity = c
self.flow = f
Quando eseguo i tuoi esempi con questa definizione di Edge
, ottengo:
>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
1
>>> f = Edge(2,3,5,10,0)
>>> f.id
1
>>> Edge._ID
2
Qual è il risultato desiderato. Tuttavia, altri hanno sottolineato che il codice originale lavorato per loro, proprio come questo codice funziona per me, così ho il sospetto che il vero problema è da qualche altra parte nel codice.
Prima di un'istanza di qualsiasi bordo, è possibile impostare la variabile di classe esplicitamente a 0 in questo modo:
Edge._ID = 0
e = Edge(1,3,5,10,0)
f = Edge(2,3,4,5,0)
E i di id sarà impostato correttamente.
Mentre le altre risposte offerti sono rispondere alla domanda posta (che è il motivo per cui io non sono intollerante con quella che inizialmente accettato), il modo corretto per farlo sarebbe quello di utilizzare itertools.count
nel seguente modo:
class Edge:
_ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
self.id = self._ID.next()