@classmethod ganz neu entdeckt (und Namespaces)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

@classmethod ganz neu entdeckt (und Namespaces)

Beitragvon gerold » Freitag 21. September 2007, 15:17

Hallo!

Ich bin mir im Moment ein wenig unsicher. Ich wollte mal ``@classmethod`` ausprobieren. Als Anwendung dafür habe ich den Zugriff auf einen in einer Textdatei gespeicherten Wert. Ich bin mir deshalb noch unsicher, da ich nicht weiß, ob man @classmethod überhaupt so verwenden soll.

Außerdem weiß ich jetzt auch nicht, ob ich den Klassennamen in diesem Fall so wie immer oder klein schreiben soll. Denn in dem Beispiel wird die Klasse ja nicht mehr wie gewohnt benutzt. -- Keine Instanz.

Ach ja, fast hätte ich es vergessen. Der Zweck dieser Übung ist, den Zugriff auf eine Textdatei, die nur einen Wert enthält, im gesamten Programm zu gewährleisten. Es soll verhindert werden, dass zwei Threads gleichzeitig die Datei zum Schreiben öffnen und sich dabei blockieren. Ich möchte die Zahl nicht im Speicher behalten, da diese kritisch ist und auch bei einem Absturz des Computers noch erhalten bleiben muss.

Code: Alles auswählen

import os
import threading

class letzte_tagab_id(object):
   
    filename = os.path.abspath("letzte_tagab_id.txt")
    lock = threading.Lock()
   
    @classmethod
    def get_id(cls):
        cls.lock.acquire()
        try:
            if os.path.isfile(cls.filename):
                f = file(cls.filename, "r")
                try:
                    return int(f.readline().strip())
                finally:
                    f.close()
            else:
                return 0
        finally:
            cls.lock.release()
   
    @classmethod
    def set_id(cls, new_id):
        cls.lock.acquire()
        try:
            f = file(cls.filename, "w")
            f.write(str(new_id))
            f.close()
        finally:
            cls.lock.release()

#test
print letzte_tagab_id.get_id()
letzte_tagab_id.set_id(15)
print letzte_tagab_id.get_id()

So oder so. Ich bin noch nicht ganz glücklich damit.

Mich würde interessieren, was ihr von dieser Art der Verwendung haltet und wie ihr es besser machen würdet.

lg
Gerold
:-)
Zuletzt geändert von gerold am Samstag 22. September 2007, 17:42, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Freitag 21. September 2007, 16:04

Ich würde auf jeden Fall das neue `with`-Statement benutzen - und zwar nicht nur für Filehandles, sondern auch für die Locks.


Klassenmethoden benutze ich persönlich, um aus einer Datenstruktur eine Instanz einer bestimmten Klasse zu erzeugen, ohne den entsprechenden Code in den Konstruktor einfügen zu müssen.

Beispiel:

Code: Alles auswählen

class Person(object):

    def __init__(self, name, age):
        self.name = name
        self.age = int(age)

    def __str__(self):
        return '<%s "%s", %d Jahre>' % (
            self.__class__.__name__, self.name, self.age)

    @classmethod
    def from_tuple(cls, t):
        return cls(*t)

t1 = ('Peter', 18)
peter = Person.from_tuple(t1)


Ich mag an Python besonders, dass man sich nicht wiederholen muss und einfach Refactoring betreiben kann: Dass der Konstruktor einen festen Namen hat, ist schon angenehm. Doch auch in der Klassenmethode kann ich eine Instanz erzeugen, ohne den Namen direkt zu verwenden. Als drittes Beispiel habe ich die String-Repräsentation eingefügt, die ich auch (wenn auch nicht ganz so kompakt) ohne Angabe des Klassennamens - aber mit selbigem als Rückgabewert - erzeugen kann. So bleibt nur eine einzige Stelle, an der der Name steht - und das ist (Achtung, Wortwitz) klasse (Alternativwortwitz: "...das ist super()").
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 18:21

Hi gerold,

Meiner Meinung sollte man Klassen nicht als Namensräume missbrauchen. Dafür gibt es Module die letztendliche auch nur Objekte sind; Singeltons wenn man so will ;)

Für dein Problem würde sich eine Singelton-Pattern (in Form einer Klasse) oder ein Borg-Pattern anbieten (Von letzteren würde ich abstand nehmen da absolut schwachsinnig-> Speicher, etc. genaueres kann man im Cookbook lesen).

Ein "sauberes" Singelton könnte so aussehen:

Code: Alles auswählen

class EggsAndSpamm(object):
    def __new__(cls, *args, **kwargs):
        if not "_instance" in cls.__dict__:
            cls._instance = object.__new__(cls)
        return cls._instance

    def meth(self):
        pass


Eine Sache gibt es aber die zu beachten ist (Auf die Alex Martelli in seinem Vortag nicht gekommen ist :roll:):
Wenn die Vererbung **sauber** klappen soll, muss ``if not "_instance" in cls.__dict__:`` anstatt von ``hasattr(cls, "_instance")`` benutzt werden!

Letztendlich ist das verhalten das gleiche wie beim Mono-State-Pattern (Borg) mit dem Unterschied das wirklich nur eine Instanz erzeugt wird und nicht 12345677**12348563774 wie beim Borg-Pattern, die alle den gleichen Zustand haben :roll: :twisted:

mfg
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 18:51

poker hat geschrieben:Meiner Meinung sollte man Klassen nicht als Namensräume missbrauchen. Dafür gibt es Module die letztendliche auch nur Objekte sind

Hallo poker!

Ich möchte die Diskussion hier nicht abbrechen, aber dazu muss ich einfach was sagen.

Du glaubst also, dass es einfacher ist, ein Modul mit nur 20 oder 30 Zeilen Code anzulegen und dieses in das Hauptmodul zu importieren, als diese paar Zeilen in einer Klasse im selben Modul abzulegen?

NEIN!!!!!!!!!!!!!!!!!!!!!!!!

Nur weil das von ein paar Leuten vorgesagt wird, ist es noch lange nicht praktikabel.

Wer sagt denn, dass Klassen nicht auch als kleine Container zur Codegliederung verwendet werden dürfen?

Ich weigere mich, meine Programme komplizierter zu machen als sie sein müssen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Beitragvon BlackJack » Freitag 21. September 2007, 19:17

Hihi, ich habe extra nicht gleich geantwortet das man so was Blödsinniges machen kann wenn man auch nichts dagegen hat Klassen als Namensräume für einfache Funktionen zu verwenden. :twisted:

Aber mal ernsthaft: So etwas kommt doch in der Regel in grösseren Programmen vor wo mehrere Module dieses "Singleton" importieren, und da ist ein eigenes Modul schon die sauberere Lösung.

Ausserdem braucht man für ein eigenes Modul nicht zwingend eine Datei:

Code: Alles auswählen

In [42]: spam = types.ModuleType('spam')

In [43]: spam
Out[43]: <module 'spam' (built-in)>


:-D
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 19:56

Hallo gerold,

Deshlab habe ich dir ja auch zu einem richtigen Singelton geraten! ;) Wie das umzusetzen ist, habe ich ja schon gepostet. Das ist viel(!!) besser als eine Klasse als Namensraum mit statischen Methoden zu **missbrauchen**, glaubs mir das hat nur nachteile :)

BTW:
Nur weil das von ein paar Leuten vorgesagt wird, ist es noch lange nicht praktikabel.
Damit kannst du mich überhaupt nicht meinen ;)

Meine Meinung resultiert nicht daraus das andere Leute mir sagen was richtig und falsch ist, sondern durch eigene Erfahrung! Z.B. schwören ja soviele auf Alex Martelli`s Borg-Pattern. Für mich ist das totaler Dreck und ein Anti-Pattern! Wozu brauch ich 10000000000 Objekte mit gleichen zustand? Nur um ein Singelton zu forcieren?! :roll: Macht sich den irgendeiner über den Speicher und Overhead Gedanken? Ne dann lieber ein richtiges wie oben angezeigt, oder zu 99% lieber gleich ein Modul :)

Also wie du siehst zieht dein Spruch "Nur weil das von ein paar Leuten vorgesagt wird" hier nicht und kann ich garnicht meinen, sonst würde ich schon längs meinen RAM mit dem Borg-Pattern assimilieren :D ;)

mfg
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 20:00

BlackJack hat geschrieben:

Code: Alles auswählen

In [42]: spam = types.ModuleType('spam')

In [43]: spam
Out[43]: <module 'spam' (built-in)>


:-D


Try this ;)

Code: Alles auswählen

In [1]: import sys
In [2]: spam = type(sys)("spam")
In [3]: spam
Out[3]: <module 'spam' (built-in)>
In [4]:

Ist IMO noch sauberer :D ``types`` (oder war das ``new``?) wird ehe in py3k gekillt.

mfg
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 20:03

Hallo BlackJack!
BlackJack hat geschrieben:So etwas kommt doch in der Regel in grösseren Programmen vor wo mehrere Module dieses "Singleton" importieren, und da ist ein eigenes Modul schon die sauberere Lösung.

Das ist hier aber nicht der Fall.
- Kleines Programm < 1000 Zeilen.
- Nur ein Modul und soll auch nicht mehr werden.
- Eine Zahl, die in eine Textdatei ausgelagert werden muss.
- Es soll ein einfacher Zugriff auf die Zahl geschaffen werden. Lesend und schreibend.

BlackJack hat geschrieben:Ausserdem braucht man für ein eigenes Modul nicht zwingend eine Datei

Ich höre. Wie würdest du diesen Fall implementieren, wenn du diese paar Zeilen Code nicht auf ein eigenes Modul auslagern sollst und nicht einfach lose zwei Funktionen irgendwo hin pappen sollst.

Es ist noch nie vorgekommen, dass ich so ein Konstrukt **nur** für den Zugriff auf einen Wert gebraucht hatte. Meist hatte ich viele Einstellungen. Und diese waren über eine Klasse "Settings" zugänglich. Diese Klasse wurde meist global instantiiert und über die Klasseninstanz "settings" zugänglich gemacht.

Code: Alles auswählen

class Settings(object):
    def __init__(...):
        # Einstellungen einlesen
        self.einstellung1 = "asdf"
        self.einstellung2 = "fffff"

# GLOBAL
settings = Settings()
...

Das Auslagern macht in vielen Programmen keinen Sinn. Auslagern, nur des Auslagerns wegen. Da muss man sich ja auf den Kopf greifen.

Statt diesem, oben gezeigten Konstrukt -- was würdest du (und wie) verwenden? Und bitte nicht in ein anderes Modul auslagern. Dann müssten auch Kleinstprogramme mit wenigen tausend Zeilen aus mehreren Modulen bestehen. -- Nur des Auslagerns wegen...

Ich werde sachlich bleiben. -- Aber bitte, keine Lösung die das Programm komplizierter macht als oben gezeigtes Konstrukt.

Die Sache mit dem Modul ohne zusätzliche Datei interessiert mich natürlich sehr. ;-) Wie würde das in diesem Fall funktionieren?

lg
Gerold
:-)

PS: In der Klasse "Settings" würde ich für das ursprüngliche Problem natürlich Properties verwenden.
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 20:06

Gerold, schade das du dir keine Mühe machen willst wenigstens meine Vorschlag auszuprobieren, geschweigen den die Posts richtig zu Lesen :roll:

Vorschläge wurden genug genannt: Singleton, Borg, ``types(sys)("blubb")``
Bin raus...
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 20:15

poker hat geschrieben:Ein "sauberes" Singelton könnte so aussehen:

Hallo poker!

Code: Alles auswählen

class EggsAndSpamm(object):
    def __new__(cls, *args, **kwargs):
        if not "_instance" in cls.__dict__:
            cls._instance = object.__new__(cls)
        return cls._instance

    def meth(self):
        return "Hallo"


print EggsAndSpamm.meth()
# TypeError: unbound method meth() must be called with EggsAndSpamm
# instance as first argument (got nothing instead)

Kein greifbarer Gewinn gegenüber der normalen, global instantiierten Klasse. Entweder muss ich jedes mal wenn ich darauf zugreifen möchte oder einmal global die Klasse instantiieren. Ich muss die Klasseninstanz also doch wieder selber erstellen. Ich werde nur daran gehindert, die Klasse mehrfach zu instantiieren. Oder was habe ich falsch verstanden?

mfg
Gerold
:-)
Zuletzt geändert von gerold am Freitag 21. September 2007, 20:24, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 20:20

poker hat geschrieben:Gerold, schade das du dir keine Mühe machen willst wenigstens meine Vorschlag auszuprobieren, geschweigen den die Posts richtig zu Lesen :roll:

Hallo poker!

Wie soll ich das jetzt machen?
Try this ;)

Code: Alles auswählen

In [1]: import sys
In [2]: spam = type(sys)("spam")
In [3]: spam
Out[3]: <module 'spam' (built-in)>
In [4]:

Einfach lose zwei Funktionen irgendwohin stellen und an "spam" binden? --> Was gewinne ich dadurch? Ich suche etwas um Ordnung im Quellcode zu schaffen und nicht um zwei lose Funktionen an ein Objekt zu binden. Und hier wieder die gleiche Frage: Was habe ich falsch verstanden?

mfg
Gerold
:-)

PS: Du steigst ja schneller aus Themen aus als ich. ;-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 20:37

gerold hat geschrieben:Kein greifbarer Gewinn gegenüber der normalen, global instantiierten Klasse. Ich muss die Klasseninstanz also doch wieder selber erstellen. Entweder, jedes mal wenn ich darauf zugreifen möchte oder einmal global. Oder was habe ich falsch verstanden?
Ja, falsch verstanden. Du musst es selbstverständlich so aufrufen ``EggsAndSpamm().meth()``.
Das mit der "doch wieder selber erstellen" ist nicht ganz richtig. Es ist Singelton. Bei ersten Aufruf von ``EggsAndSpamm()`` wird die durch __new__ erzeugt Instanz in ``_instance`` gespeichert. Bei jeden weiteren Aufruf von ``EggsAndSpamm()` wird keine neue erstellt, sondern die bereits erzeugt wider zurückgegeben :)

``print id(EggsAndSpamm()), id(EggsAndSpamm())`` => 10400816 10400816

Kein greifbarer Gewinn gegenüber der normalen, global instantiierten Klasse.

Doch es gibt ein greifbaren Gewinn. Du kannst __iter__ implementieren und benutzen, das du bei einer nicht instantiierten Klasse nicht nutzen kannst. Du kannst in Grunde alles machen wie mit einer normalen Klassen-Instanz. Das alles geht nicht wenn man die Klasse direkt als Namensraum nutzt (Ok, mit Modulen geht es auch nicht).

Falls du diese Funktionalität nicht benötigst, kannst du auch folgendes machen:

Code: Alles auswählen

In [1]: import sys
In [2]: spam = type(sys)("spam")
In [3]: spam
Out[3]: <module 'spam' (built-in)>
In [4]: cfg = type(sys)("cfg")
In [5]: cfg.foo = "Moin"
In [6]: cfg
Out[6]: <module 'cfg' (built-in)>
In [7]: dir(cfg)
Out[7]: ['__doc__', '__name__', 'foo']


Daran kannst du auch Funktionen binden, eben alles was mit einen Modul geht. Meiner Erfahrung und Meinung nach sind beide Lösung die saubersten. Wie gesagt das ist nur **meine Meinung**. Ich habe lange Zeit auch Klassen als Namensräume genutzt und bin dann irgendwann auf "richtige" Singeltons umgestiegen, nach dem ich viele nachteile hatte (Auserdem sind wir ja nicht hier bei Java SCNR;))

Mein Fazit:
Wenn ich eine einmalige Instanz von etwas brauche für globalen Zugriff (Settings, etc), der mir aber auch die Freiheit geben soll __iter__, __eq__, etc zu nutzen => Singelton in form eine Klasse mit obigen __new__-code.

Wenn ich aber nur einen globalen Namensraum brauche der einmalig ist (auch für Settings, etc) => Ein Modul oder ``type(sys)("eggs")``.

``@classmethod`` nutze ich nur für alternative Konstruktoren, damit man das object noch anders erzeugen kann.

mfg

P.S.: Aber letztendlich ist das immer die Entscheidung des anderen. Wenn du glaubst das du das in Form einer Klasse mit ``@classmeth`` brauchst und dich damit wohler fühlst, ist das O.K. und machs dann.

Letztendlich ist die "reine" Lehre nur soviel Wert bis man auf deren Grenzen stößt, das aber in dem Fall halt nicht gegeben ist. Deshalb empfehlen wir dir auch de anderen Lösungen weil sie "sauberer" und "pythonischer" sind.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 20:57

poker hat geschrieben:Wenn du glaubst das du das in Form einer Klasse mit ``@classmeth`` brauchst und dich damit wohler fühlst, ist das O.K. und machs dann.

Hallo poker!
Hallo BlackJack!

Das ist es ja! Ich finde @classmethod nicht so intuitiv wie das Beispiel in diesem Beitrag http://www.python-forum.de/post-78121.html#78121

Singleton's halte ich für den ganz oben genannten Fall für überzogen. Es geht ja nur darum, für das gesamte Modul zwei Funktionen in einem Namensraum zur Verfügung zu stellen. Sie gehören logisch zusammen. Und weil ich gerne in abeschlossenen Einheiten (Containern) denke, wäre es, für mich persönlich, eine große Hilfe, wenn diese beiden Funktionen nicht irgendwo herum liegen, sondern sich in einem abgeschlossenen Bereich (z.B. eine Klasse) befinden.

Das Binden der beiden Funktionen an ein intern erstelltes Modul-Objekt ist ja gar nicht mal so schlecht. Jetzt fehlt noch die *optische* Kapselung. -- Der Quellcode darf seine Eleganz nicht verlieren. Dinge die zusammen gehören, müssen bei mir optisch zusammen sein. Ich verwende viel Zeit darin, mir die einfachen, intuitiven, leicht reproduzierbaren Möglichkeiten von Python raus zu picken und in meinen Programmen zu verwenden.

Jetzt ist ein Experiment mit @classmethod an der Reihe gewesen. Bis jetzt ist mein Fazit so: Ich brauche für jede Methode einen zusätzlichen Dekorator und weiß nicht, ob ich die Klasse groß oder klein schreiben soll. Das ist bis jetzt noch kein Gewinn gegenüber der alten Methode, in der ich die Klasse als Namensraum verwendet habe.

Wisst ihr, was ich eigentlich suche?

So etwas, oder etwas ähnliches. Also ein Namespace oder ein "Modul" im Modul:

Code: Alles auswählen

namespace letzte_tagab_id:
    filename = "xyxcv"
   
    def get_id():
        return "asdf"

    def set_id(new_id):
        ...

letzte_tagab_id.set_id(10)
print letzte_tagab_id.get_id()

Bis jetzt kommt das hier immer noch recht nahe an das was ich haben möchte ran:

Code: Alles auswählen

class Settings(object):
    def __init__(...):
        # Einstellungen einlesen
        self.einstellung1 = "asdf"
        self.einstellung2 = "fffff"

# GLOBAL
settings = Settings()
...


mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Freitag 21. September 2007, 21:24

Kurz für mich zusammengefasst:
Dir geht es also nur darum nur ein Modul zu haben = dein Programm. Nun suchst du nach einer Möglichkeit zusammengehöriges Optisch zu strukturieren und darüber zuzugreifen.

Ich hab zwar dein Problem (hoffentlich) nun erfasst aber es will sich mir nicht so ganz erschließen weshalb es ein Problem darstellt? Warum packst du es nicht einfach in der Klasse und erzeugst eine Instanz. Der Rest vom Modul greift dann auf die Instanz zu :) Ich weiß, global's sind verpönt aber hey, es ist ja nicht Modulweit sondern nur in dem einen und es werden eben Daten bereitgestellt die Global verfügbar sein müssen! Punkt.
Kurz und Schmerzlos:

Code: Alles auswählen

# Global Settings
class Config(object):
    pass

# Other stuff
class CheesShop(object):
    pass

# Globals
cfg = Config()
chees = CheesShop()

# do something

Nun kann der Rest eben darauf zugreifen.

Falls das auch nicht O.K. ist kannst du folgendes Fake-Singelton-Pattern nutzen :D

Code: Alles auswählen

# Global Settings
class cfg(object):
    pass
cfg = cfg()
# Other stuff
class chees(object):
    pass
chees = chees()

# do something

Wird auch hin und wider gern genommen, aber gefällt mir persönlich nicht. Aber damit hast du quasi auch Singeltons :D

mfg
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 21. September 2007, 21:27

Hallo!

Also ganz ehrlich. Und ich schäme mich auch nicht dafür. :-) Derzeit würde ich (ohne Properties und ohne Rücksicht auf "set" im Quellcode) das Beispielproblem immer noch so angehen:

Code: Alles auswählen

import os
import threading


class LetzteTagabId(object):

    filename = os.path.abspath("letzte_tagab_id.txt")
    _lock = threading.Lock()
   
    def get(self):
        LetzteTagabId._lock.acquire()
        try:
            if os.path.isfile(LetzteTagabId.filename):
                f = file(LetzteTagabId.filename, "r")
                try:
                    return int(f.readline().strip())
                finally:
                    f.close()
            else:
                return 0
        finally:
            LetzteTagabId._lock.release()
   
    def set(self, new_id):
        LetzteTagabId._lock.acquire()
        try:
            f = file(LetzteTagabId.filename, "w")
            f.write(str(new_id))
            f.close()
        finally:
            LetzteTagabId._lock.release()

# GLOBAL
letzte_tagab_id = LetzteTagabId()

#test
print letzte_tagab_id.get()
letzte_tagab_id.set(25)
print letzte_tagab_id.get()

Unverbesserlich? Nein. Ich bin für schönere Lösungen offen. Sie sollten nur nicht den Code zerreißen. Ich denke sehr viel über Sinn und Unsinn vieler Codekonstrukte nach (wieder mal keine Freundin ;-) ) und wenn mich etwas überzeugt, dann setze ich es in Zukunft in meinen Programmen ein. Das ist auch der einzige Grund für diesen Topic. Ich will herausfinden, ob es schönere Möglichkeiten gibt.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.

Wer ist online?

Mitglieder in diesem Forum: Google [Bot], kbr