2010-11-17 17 views
5

Me gustaría poder crear un objeto datetime con datetime.datetime.now() PyYAML. Es fácil llamar a algunas funciones:Cómo crear un objeto datetime con PyYAML

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

Sin embargo, me parece que no puede encontrar la manera de conseguir un datetime.now(). He intentado tantas permutaciones con llamadas a eso usando los diversos python yaml tags.

todos éstos fallan:

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 

Respuesta

5

Creo que este ejemplo se consigue lo que estás buscando:

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

Sin embargo, creo que es demasiado exagerado porque la sintaxis !!python/object apoyado por PyYAML no se supone que llamar a métodos de clase (es datetime.datetime.now realmente me gusta un método de fábrica "estático" para objetos datetime). Como usted ha dicho, esto es más simple (aunque no es lo que está buscando):

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

Otra solución alternativa posible sería la creación de una función de ayuda a medida que envuelve la llamada a datetime.datetime.now de modo que sea fácilmente serializado con !!python/object/apply. La desventaja es que esta serialización no sería portátil en un entorno donde no se encuentra esta función personalizada.

De todos modos, en mi opinión, no tiene demasiado sentido serializar un valor que siempre devuelve la fecha actual (que en realidad sería el momento en que se analizó el YAML). PyYAML proporciona este atajo para serializar una marca de tiempo determinada:

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

Muy agradable. Estoy de acuerdo en que este es un caso de uso un poco intrincado, pero su solución parece ser la forma más fácil de lograrlo. Por contexto, estoy investigando el uso de YAML para generar datos de prueba que se cargarán a través de Django. Tener datos generados cuando se carga el archivo sería un gran beneficio para muchas pruebas. ¡Gracias por la respuesta! – brianz

+1

fwiw, con 'apply' eliminado en python 3 el ejemplo ya no funciona. Dicho esto, en realidad no estoy buscando hacer esto, me encontré con esta respuesta mientras investigaba :) (¡wow 'pyyaml' es una locura!) –

0

El problema es que el objeto no tiene un método que PyYAML necesita para generar automáticamente la representación YAML. ¿Por qué no simplemente hacer datetime.datetime.now().isoformat() y almacenar esa cadena en su lugar?

Alternativamente, podría poner las propiedades deseadas del objeto datetime en un diccionario y cargar eso.

Si desea almacenar la cadena isoformat, simplemente ponerlo en una cadena y lo descarga:

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

cuando lo lea de nuevo, utiliza el strptime() método:

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

Por supuesto, hilarante, me acabo de dar cuenta de que puede hacer:

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

Si carga eso con yaml.load(yaml_timestamp), se encontrará en posesión de un nuevo objeto brillante datetime.datetime.

+0

El problema es que me gustaría que esto se genere dinámicamente cuando se carga el archivo yaml. ¿Su segunda solución lograría eso? – brianz

+0

En realidad, leí mal su pregunta; Estaba pensando que querías almacenar el objeto datetime. Dicho esto, puede usar el método '.isoformat()' para generar una cadena, luego use 'strptime()' (http://docs.python.org/library/datetime.html#datetime.datetime.strptime) para convierta la cadena a un objeto datetime. – syrion

+0

¿Y cómo exactamente harías eso dinámicamente en un archivo yaml usando pyyaml? – brianz

Cuestiones relacionadas