Seite 1 von 1
Einfacher ID-Generator
Verfasst: Mittwoch 25. Februar 2004, 00:38
von Dookie
Hallo Leute,
gerade bei GUI oder auch XML-Programmierung kommt man öfter in die Verlegenheit, eindeutige IDs für Elemente zu erstellen. Ich hab mir dafür mal eine kleine Funktion geschrieben, die ich gerne an Euch weitergebe.
Code: Alles auswählen
def generate_ID(name, fmt="%s_%03d", start=1):
""" Erzeuge ID-String mit "name" und fortlaufender Nummer im Format "fmt" """
id = getattr(generate_ID,name,start)
setattr(generate_ID, name, id+1)
return fmt % (name, id)
Gruß
Dookie
Verfasst: Mittwoch 25. Februar 2004, 06:44
von Milan
Hi. Ich weiß nicht ganz so... mir gefällt das nicht, dass man der Funktion Atribute verpasst, als wäre sie eine Klasse. Geht es denn nicht auch mit global eine Variable hochzuzählen? Da müsste dann zwar vielleicht der Name zusammen mit der ID in einem Tupel gespeichert werden, aber das kommt mir irgendwie sauberer vor...
Milan
Verfasst: Mittwoch 25. Februar 2004, 09:33
von joerg
Milan hat geschrieben: ...mir gefällt das nicht, dass man der Funktion Atribute verpasst, als wäre sie eine Klasse...
Das geht mir ähnlich, aber vielleicht bin ich es auch nur nicht gewöhnt.
Jedenfalls geht es IMO auch eleganter, da man ja mit Hilfe von __call__ beliebige Instanzen wie Funktionen aussehen lassen kann. Ich mache es immer so:
Code: Alles auswählen
class GenID:
def __init__(self, start=0):
self.count = start
def __call__(self, name, fmt="%s_%03d"):
self.count += 1
return fmt % (name, self.count)
genId = GenID()
if __name__ == '__main__':
for i in range(10):
print genId('bla')
Jörg
Verfasst: Mittwoch 25. Februar 2004, 13:52
von Dookie
Naja, globale Variablen vermeide ich wie der Teufel das Weihwasser.
Hier mal eine Version, die kein Attribut der Funktion setzt.
Code: Alles auswählen
def id_generate(name, fmt="%s_%03d", _dict={}):
id = _dict.get(name,0)+1
_dict[name] = id
return fmt % (name, id)
Gruß
Dookie
Verfasst: Mittwoch 25. Februar 2004, 17:54
von Milan
Hi. Die Version find ich wesentlich besser
. Sicher haben globale Variablen so ihre Risiken, weil man nie weiß, wie der Nutzer damit umgeht. Dessen bin ich mir bewusst, was dabei passieren kann. Aber das hier ist der Königsweg... mutable Objects haben schon ihre Vorteile
Milan
re:
Verfasst: Mittwoch 19. Mai 2004, 13:12
von HarryH
Hallo,
Dookie hat folgendes geschrieben:
Code: Alles auswählen
def id_generate(name, fmt="%s_%03d", _dict={}):
id = _dict.get(name,0)+1
_dict[name] = id
return fmt % (name, id)
Ich habe nur eine kurze Frage:
Warum wird der letzte Eintrag von "_dict" nicht durch den erneuten Aufruf der Funktion gelöscht, da beim Aufruf doch "_dict={}" gesetzt wird?
Verfasst: Mittwoch 19. Mai 2004, 14:01
von Dookie
Hi Harry,
_dict wird auf ein leeres Dictionary ({}) gesetzt, wenn der Interpreter das Funktionsobjekt erzeugt. Also wenn die def Anweisung ausgeführt wird.
In der Funktion wird dem Dictionary ein neues Schlüssel-Werte-Paar hinzugefügt oder modifiziert, es ist immer noch das gleiche Dictionary, welches bei der Erzeugung des Funktionsobjekts angelegt wurde.
Siehe auch pydoc def
Gruß
Dookie
re:
Verfasst: Mittwoch 19. Mai 2004, 14:58
von HarryH
Ich verstehe immer noch nicht wie Python sich das merkt.
Wenn ich folgenden Code ausführe, rufe ich die Funktion doch immer wieder neu auf. Das "_dict" müßte doch dann immer wieder auf "{}" gesetzt werden?
Code: Alles auswählen
for create in xrange(100):
id = id_generate("Var")
print id
Aber der letzte Eintrag im _dict bleibt trotz erneutem Aufruf gespeichert!
Und warum funktioniert es dann bei folgendem Code nicht?
Code: Alles auswählen
def var(v=1):
v+=1
return v
for i in xrange(10):
print var()
Verfasst: Mittwoch 19. Mai 2004, 15:29
von Dookie
Die vordefinierten Parameter sind wie Zettelchen, auf denen Steht die Adresse eines Objekts. Wenn der Interpreder den Code nach dem def statement, der den Funktionscode abarbeitet wird für jeden Parameter der schon einen Wert zugeweisen bekommen hat ein entsprechendes Objekt angelegt. Wenn dieser Parameter ein Mutable Objekt ist (Dictionary oder Liste), so kann dieses Objekt verändert werden.
Code: Alles auswählen
In [1]: def test(v=[1]):
...: v[0] +=1
...: print v[0]
...:
In [2]: test()
2
In [3]: test()
3
In [4]: test()
4
v ist nur ein Zettelchen auf dem die Adresse einer Liste steht, verändert wird ein Eintrag der Liste, nicht wie bei Deinem Beispiel v selber.
Gruß
Dookie
re:
Verfasst: Mittwoch 19. Mai 2004, 15:48
von HarryH
A, jetzt verstehe ich das
Vielen Dank!
Re: Einfacher ID-Generator
Verfasst: Freitag 12. April 2013, 18:21
von Nobuddy
Hallo Dookie,
Danke für Deinen id_generator, funktioniert prima!
Grüße Nobuddy
Re: Einfacher ID-Generator
Verfasst: Freitag 12. April 2013, 21:15
von /me
Nobuddy hat geschrieben:Danke für Deinen id_generator, funktioniert prima!
Mit diesem Posting hast du vermutlich den Rekord gebrochen und bist dadurch dem Verderben anheim gefallen. Dermaßen alte Threads darf definitiv nur der offizielle Zombiemeister dieses Forums wiederbeleben. Die Konsequenzen für dich werden furchtb ... nein, ich sage jetzt nichts dazu ...
Re: Einfacher ID-Generator
Verfasst: Samstag 13. April 2013, 10:23
von Leonidas
Ist außerdem etwas komisch für mich alte Threads von Dookie wiederzusehen
Re: Einfacher ID-Generator
Verfasst: Montag 3. Juni 2013, 17:11
von Nobuddy
upsss, hatte nicht auf das Verallsdatum geachtet ....