Automatische Inkrementierungs-IDs für Klasseninstanzen
-
25-10-2019 - |
Frage
Haftungsausschluss: Dies ist für ein Semesterprojekt, an dem ich derzeit arbeite. Meine Frage bezieht sich auf ein Detail der Implementierungsebene und ist nicht Teil des Bewertungsschemas. Ich schreibe diesen Code nur, um die Theorie zu testen, die ich für das Papier vorschlage, das ich schreiben werde.
Außerdem habe ich die Antworten für berücksichtigt diese Frage Mit wenig Glück, also betrachten Sie dies nicht als Duplikat dieser Frage
Das Problem:
Ich habe ein Diagramm (g = (v, e)). Irgendwann in meinem Algorithmus muss ich dies in einen Hypergraph (in gewissem Sinne) verwandeln, indem ich mehrere Knoten "zusammenbricht" (z. B., v_1, v_2, ..., v_n
) in einen Knoten (sagen wir, v
). Im Zusammenhang mit dem Problem bedeutet dies, dass ich die Kanten ändern muss E
so dass jede Kante e
zwischen einem von v_1, v_2, v_n
und jeder andere Knoten u
in V
wird so geändert, dass e
ist jetzt dazwischen u
und v
.
Um festzustellen, dass es jetzt mehrere unterschiedliche Kanten zwischen einem Knotenpaar existieren kann, muss ich für jede Kante eine eindeutige Kennung erstellen. Ich habe versucht, dies mit und mit ID zu tun, was ich derzeit nicht ordnungsgemäß implementieren kann.
Das habe ich versucht:
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
Wenn ich jedoch versuche, eine neue Kante zu instanziieren, erhalte ich den folgenden Fehler:
>>> 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
BEARBEITEN:
Mit den Vorschlägen einiger Antworten konnte ich den Instanziationsfehler beheben. Ein weiterer Fehler bleibt jedoch bestehen. Hier ist mein Code und die Fehler:
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
Fehler:
>>> 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
Ich würde mich über jede Hilfe freuen
Vielen Dank
Lösung
Sie können immer noch verwenden self
um an zu kommen _ID
.
self.id = self._ID
self.__class__._ID += 1
Wenn Sie CPython verwenden, können Sie eine faule Mann -ID haben:
class Edge(object):
@property
def id(self): return id(self)
Andere Tipps
Ihr bearbeiteter Code behandelt _ID
Als wäre es eine Instanzvariable, keine Klassenvariable. Basierend auf der Antwort von Matt Joiner, was ich denke, ist dies Folgendes:
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
Wenn ich Ihre Beispiele mit dieser Definition von durchführe Edge
, Ich bekomme:
>>> 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
Welches ist das gewünschte Ergebnis. Andere haben jedoch darauf hingewiesen, dass Ihr ursprünglicher Code für sie funktioniert hat, genau wie dieser Code für mich funktioniert. Ich vermute also, dass das eigentliche Problem woanders in Ihrem Code liegt.
Bevor Sie eine Kante instanziieren, können Sie die Klassenvariable ausdrücklich auf 0 festlegen: SO:
Edge._ID = 0
e = Edge(1,3,5,10,0)
f = Edge(2,3,4,5,0)
Und die IDs werden ordnungsgemäß eingestellt.
Während die anderen angebotenen Antworten die gestellte Frage beantworten (weshalb ich die, die ich ursprünglich akzeptiert habe), ist die richtige Art und Weise, wie ich dies zu verwenden habe itertools.count
folgendermaßen:
class Edge:
_ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
self.id = self._ID.next()