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 :D . 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 :wink:

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! :wink:

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! :wink:
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 .... :D