Как создать объект datetime с PyYAML - PullRequest
8 голосов
/ 17 ноября 2010

Я хотел бы иметь возможность создать объект datetime с datetime.datetime.now() PyYAML.Некоторые функции легко вызвать:

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

Однако я не могу понять, как получить datetime.now().Я пробовал столько же перестановок с обращениями к нему, используя различные теги python yaml .

Все эти ошибки:

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

Ответы [ 2 ]

6 голосов
/ 17 ноября 2010

Я думаю, что этот пример достигает того, что вы ищете:

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

Однако, я думаю, что это слишком надумано, потому что синтаксис !!python/object, поддерживаемый PyYAML, не должен вызывать методы класса (datetime.datetime.now на самом деле похож на "статический" фабричный метод для объектов datetime). Как вы сказали, это проще (хотя и не то, что вы ищете):

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

Другой возможный обходной путь - создание пользовательской вспомогательной функции, которая переносит вызов на datetime.datetime.now, чтобы его можно было легко сериализовать с !!python/object/apply. Недостатки в том, что эта сериализация не будет переносимой в среду, где эта пользовательская функция не найдена.

В любом случае, по моему мнению, не имеет большого смысла сериализовать значение, которое всегда возвращает текущую дату и время (что фактически будет временем, когда YAML был проанализирован). PyYAML предоставляет этот ярлык для сериализации определенной временной метки:

dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""")
0 голосов
/ 17 ноября 2010

Проблема в том, что у объекта нет метода, который необходим PyYAML для автоматического создания представления YAML. Почему бы просто не сделать datetime.datetime.now().isoformat() и вместо этого сохранить эту строку?

Кроме того, вы можете поместить нужные свойства объекта datetime в словарь и загрузить его.

Если вы хотите сохранить строку изоформата, просто поместите ее в строку и дамп:

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

Когда вы читаете его обратно, используйте метод strptime():

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

Конечно, весело, я только что понял, что вы можете просто сделать:

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

Если вы загрузите его с помощью yaml.load(yaml_timestamp), вы обнаружите, что обладаете новым блестящим datetime.datetime объектом.

...