Einfacher ID-Generator

Code-Stücke können hier veröffentlicht werden.
Antworten
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 25. Februar 2004, 00:38

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
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Mittwoch 25. Februar 2004, 06:44

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
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Mittwoch 25. Februar 2004, 09:33

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
"Sie sind nicht berechtigt, unrechtmäßige Kopien dieses Datenträgers zu erstellen." - Microsoft-Weisheit auf einer CD von MS-VisualC++-6.0
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 25. Februar 2004, 13:52

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
Zuletzt geändert von Dookie am Montag 12. Juli 2004, 21:02, insgesamt 1-mal geändert.
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Mittwoch 25. Februar 2004, 17:54

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
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Mittwoch 19. Mai 2004, 13:12

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?
Gruß, Harry
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 19. Mai 2004, 14:01

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
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Mittwoch 19. Mai 2004, 14:58

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()
Gruß, Harry
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Mittwoch 19. Mai 2004, 15:29

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
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Mittwoch 19. Mai 2004, 15:48

A, jetzt verstehe ich das
Vielen Dank!
Gruß, Harry
Nobuddy
User
Beiträge: 743
Registriert: Montag 30. Januar 2012, 16:38

Freitag 12. April 2013, 18:21

Hallo Dookie,

Danke für Deinen id_generator, funktioniert prima! :wink:

Grüße Nobuddy
Benutzeravatar
/me
User
Beiträge: 3191
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Freitag 12. April 2013, 21:15

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 ...
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 13. April 2013, 10:23

Ist außerdem etwas komisch für mich alte Threads von Dookie wiederzusehen :-|
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Nobuddy
User
Beiträge: 743
Registriert: Montag 30. Januar 2012, 16:38

Montag 3. Juni 2013, 17:11

upsss, hatte nicht auf das Verallsdatum geachtet .... :D
Antworten