Come creare un oggetto datetime con PyYAML
Domanda
Mi piacerebbe essere in grado di creare un oggetto datetime con datetime.datetime.now()
PyYAML. E 'facile chiamare alcune funzioni:
>>> y = """#YAML
... description: Something
... ts: !!python/object/apply:time.time []"""
>>> yaml.load(y)
{'description': 'Something', 'ts': 1289955567.940973}
>>>
Tuttavia, non posso sembrare calcolare fuori come ottenere un datetime.now()
. Ho provato il maggior numero di permutazioni con le chiamate che utilizzano i vari pitone yaml tag .
Questi tutti fallire:
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
Soluzione
Credo che questo esempio realizza quello che stai cercando:
dt = yaml.load("""dt: !!python/object/apply:apply
- !!python/object/apply:getattr
- !!python/name:datetime.datetime
- now
- []
""")
Tuttavia, penso che sia troppo inverosimile, perché la sintassi !!python/object
supportata da PyYAML non è supposto per metodi di classe chiamata (datetime.datetime.now
è in realtà come un metodo factory "statico" per datetime oggetti). Come lei ha detto, questo è più semplice (anche se non quello che stai cercando):
dt = yaml.load("dt: !!python/object/apply:time.gmtime []")
dt = yaml.load("dt: !!python/object/apply:time.time []")
Un altro possibile work-around sarebbe quella di creare una funzione di supporto personalizzato che avvolge la chiamata a datetime.datetime.now
in modo che sia facilmente serializzato con !!python/object/apply
. Il contro è che questo serializzazione non sarebbe portatile ad un ambiente in cui non si trova questa funzione personalizzata.
In ogni caso, a mio parere non ha molto senso per serializzare un valore che restituisce sempre il datetime corrente (che sarebbe in realtà il momento in cui il YAML è stato analizzato). PyYAML prevede questa scorciatoia per la serializzazione di una certa data e ora:
dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""")
Altri suggerimenti
Il problema è che l'oggetto non dispone di un metodo che PyYAML ha bisogno di generare automaticamente la rappresentazione YAML. Perché non basta fare datetime.datetime.now().isoformat()
e negozio che stringa invece?
In alternativa, si potrebbe mettere le proprietà desiderate dell'oggetto datetime
in un dizionario e il carico che.
Se si vuole memorizzare la stringa isoformat, è sufficiente mettere in una stringa e discarica:
timestamp = datetime.datetime.now().isoformat()
Quando si legge indietro nel, utilizzare il metodo strptime()
:
new_dt_object = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')
Naturalmente, esilarante, ho appena capito che si può solo fare:
yaml_timestamp = yaml.dump({'timestamp': datetime.datetime.now()})
Se si carica che con yaml.load(yaml_timestamp)
, vi ritroverete in possesso di un nuovo oggetto datetime.datetime
lucido.