Как создать объект datetime с помощью PyYAML
Вопрос
Я хотел бы иметь возможность создать объект datetime с помощью datetime.datetime.now()
ПиЯМЛ.Некоторые функции легко вызвать:
>>> 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
Решение
Я думаю, что этот пример достигает того, что вы ищете:
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'""")
Другие советы
Проблема в том, что у объекта нет метода, который нужен 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
объект.