2010-11-17 7 views
5

Ich möchte in der Lage sein, ein Datetime-Objekt mit datetime.datetime.now() PyYAML erstellen. Es ist einfach, einige Funktionen zu nennen:So erstellen Sie ein Datetime-Objekt mit PyYAML

>>> y = """#YAML 
... description: Something 
... ts: !!python/object/apply:time.time []""" 
>>> yaml.load(y) 
{'description': 'Something', 'ts': 1289955567.940973} 
>>> 

Allerdings kann ich nicht scheinen, um herauszufinden, wie man ein datetime.now() zu bekommen. Ich habe so viele Permutationen mit Anrufen versucht, die die verschiedenen python yaml tags verwenden.

all diese fehlschlagen:

tests = [ 
     'dt: !!python/object:datetime.datetime.now []', 
     'dt: !!python/object/new:datetime.datetime.now []', 
     'dt: !!python/object/apply:datetime.datetime.now []', 
] 

for y in tests: 
    try: 
     print yaml.load(y) 
    except Exception, err: 
     print '==>', err 

Antwort

5

Ich denke, dieses Beispiel erreicht, was Sie suchen:

dt = yaml.load("""dt: !!python/object/apply:apply 
    - !!python/object/apply:getattr 
     - !!python/name:datetime.datetime 
     - now 
    - [] 
""") 

Aber ich denke, es ist zu weit hergeholt ist, weil die !!python/object Syntax von PyYAML unterstützt wird nicht nennen Klassenmethoden soll (datetime.datetime.now ist tatsächlich wie eine "statische" Factory-Methode für Datetime-Objekte). Wie Sie sagten, ist dies einfacher (wenn auch nicht das, was Sie suchen):

dt = yaml.load("dt: !!python/object/apply:time.gmtime []") 
dt = yaml.load("dt: !!python/object/apply:time.time []") 

Eine weitere mögliche Behelfslösung wäre eine eigene Hilfsfunktion zu erstellen, um den Anruf zu datetime.datetime.now wickelt, so dass es leicht serialisiert mit . Der Nachteil ist, dass diese Serialisierung nicht in eine Umgebung portierbar ist, in der diese benutzerdefinierte Funktion nicht gefunden wird.

Wie auch immer, meiner Meinung nach macht es nicht viel Sinn, einen Wert zu serialisieren, der immer die aktuelle datetime zurückgibt (was tatsächlich die Zeit wäre, als der YAML geparst wurde). PyYAML bietet diese Abkürzung für die Serialisierung eines bestimmten Zeitstempels:

dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""") 
+0

Sehr schön. Ich stimme zu, dass dies ein etwas komplizierter Anwendungsfall ist, aber Ihre Lösung scheint der einfachste Weg zu sein. Für den Kontext untersuche ich mit YAML Testdaten, die über Django geladen werden. Das Erzeugen von Daten, wenn die Datei geladen wird, wäre ein großer Vorteil für viele Tests. Danke für die Antwort! – brianz

+1

fwiw, mit 'apply' in Python 3 entfernt, funktioniert das Beispiel nicht mehr. Das heißt, ich bin nicht wirklich auf der Suche nach dies nur stolperte über diese Antwort, während einige Nachforschungen :) (wow 'pyyaml' ist verrückt!) –

0

Das Problem ist, dass das Objekt nicht eine Methode hat, die PyYAML benötigt, um automatisch die YAML Darstellung zu erzeugen. Warum nicht einfach datetime.datetime.now().isoformat() und diese Zeichenfolge speichern?

Alternativ könnten Sie die gewünschten Eigenschaften des Objekts datetime in ein Wörterbuch einfügen und dieses laden.

Wenn Sie die isoformat String speichern wollen, legen Sie sie einfach in einen String und Dump es:

timestamp = datetime.datetime.now().isoformat()

Wenn Sie es wieder einzulesen, verwenden Sie die strptime() Methode:

new_dt_object = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')

Natürlich, urkomisch, ich habe gerade festgestellt, dass Sie einfach tun können:

yaml_timestamp = yaml.dump({'timestamp': datetime.datetime.now()})

Wenn Sie das mit yaml.load(yaml_timestamp) laden, befinden Sie sich im Besitz eines glänzenden neuen datetime.datetime Objekts.

+0

Das Problem ist, dass ich möchte, dass dies dynamisch generiert wird, wenn die YAML-Datei geladen ist. Würde Ihre zweite Lösung dies erreichen? – brianz

+0

Eigentlich habe ich deine Frage falsch gelesen; Ich dachte, du möchtest das Datetime-Objekt speichern. Das heißt, Sie könnten die Methode '.isoformat()' verwenden, um eine Zeichenfolge zu generieren, und dann 'strptime()' (http://docs.python.org/library/datetime.html#datetime.datetime.strptime) verwenden Konvertieren Sie die Zeichenfolge in ein Datetime-Objekt. – syrion

+0

Und wie genau würden Sie das dynamisch in einer Yaml-Datei mit Pyyaml ​​tun? – brianz