代码之家  ›  专栏  ›  技术社区  ›  brianz

如何使用PyYAML创建datetime对象

  •  8
  • brianz  · 技术社区  · 14 年前

    我希望能够创建一个日期时间对象 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 tags .

    这些都失败了:

    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 回复  |  直到 14 年前
        1
  •  6
  •   scoffey    14 年前

    我想这个例子达到了你想要的:

    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 []")
    

    另一种可能的解决方法是创建一个自定义的helper函数,该函数将调用包装为 日期时间.datetime.now 所以它很容易被序列化 !!python/object/apply . 缺点是,此序列化无法移植到找不到此自定义函数的环境中。

    无论如何,在我看来,序列化一个总是返回当前日期时间(实际上是解析YAML的时间)的值没有太大意义。PyYAML提供了序列化特定时间戳的快捷方式:

    dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""")
    
        2
  •  0
  •   asthasr    14 年前

    问题是对象没有PyYAML自动生成YAML表示所需的方法。为什么不干脆 datetime.datetime.now().isoformat() 把那根绳子存起来?

    或者,您可以将 datetime 对象并加载它。

    如果要存储isoformat字符串,只需将其放入字符串并转储即可:

    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 反对。