python - 解析 YAML 时忽略日期和时间

标签 python yaml

我正在编写一个脚本,将一系列 YAML 文件转换为单个 JSON blob。我有一个像这样的 YAML 文件:

---
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation ECS Sample
Parameters:
    - SolrCloudInstanceType:
        Type: String
        Description: Solr Cloud EC2 Instance Type
        Default: m3.2xlarge
Resources:
    - ContainerInstance:
        Type: AWS::EC2::Instance
        Properties:
            InstanceType: m3.xlarge

我是这样加载的

import yaml

with open('base.yml', 'rb') as f:
    result = yaml.safe_load(f)

有趣的是,如果我检查 AWSTemplateFormatVersion,我会得到一个 Python datetime.date 对象。这会导致我的 JSON 输出失败:

>>> json.dump(result, sys.stdout, sort_keys=True, indent=4)
{
    "AWSTemplateFormatVersion": Traceback (most recent call last):
  File "./c12n-assemble", line 42, in <module>
    __main__()
  File "./c12n-assemble", line 25, in __main__
    assembler.assemble()
  File "./c12n-assemble", line 39, in assemble
    json.dump(self.__result, self.__output_file, sort_keys=True, indent=4, separators=(',', ': '))
  File "/usr/lib/python2.7/json/__init__.py", line 189, in dump
    for chunk in iterable:
  File "/usr/lib/python2.7/json/encoder.py", line 434, in _iterencode
    for chunk in _iterencode_dict(o, _current_indent_level):
  File "/usr/lib/python2.7/json/encoder.py", line 408, in _iterencode_dict
    for chunk in chunks:
  File "/usr/lib/python2.7/json/encoder.py", line 442, in _iterencode
    o = _default(o)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.date(2010, 9, 9) is not JSON serializable

有没有办法强制 YAML 解析器对它认为的日期或日期+时间不“智能”,而只解析字符串?

最佳答案

您可以扩展 PyYAML 加载器并删除时间戳或其他类型的隐式标记,如下所示:

class NoDatesSafeLoader(yaml.SafeLoader):
    @classmethod
    def remove_implicit_resolver(cls, tag_to_remove):
        """
        Remove implicit resolvers for a particular tag

        Takes care not to modify resolvers in super classes.

        We want to load datetimes as strings, not dates, because we
        go on to serialise as json which doesn't have the advanced types
        of yaml, and leads to incompatibilities down the track.
        """
        if not 'yaml_implicit_resolvers' in cls.__dict__:
            cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()

        for first_letter, mappings in cls.yaml_implicit_resolvers.items():
            cls.yaml_implicit_resolvers[first_letter] = [(tag, regexp) 
                                                         for tag, regexp in mappings
                                                         if tag != tag_to_remove]

NoDatesSafeLoader.remove_implicit_resolver('tag:yaml.org,2002:timestamp')

按如下方式使用此备用加载器:

>>> yaml.load("2015-03-22 01:49:21", Loader=NoDatesSafeLoader)
'2015-03-22 01:49:21'

作为引用,原始行为是:

>>> yaml.load("2015-03-22 01:49:21")
datetime.datetime(2015, 3, 22, 1, 49, 21)

关于python - 解析 YAML 时忽略日期和时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34667108/

相关文章:

python - 从 Pandas DataFrame 中选择一列中具有相同值但另一列中具有不同值的行

python - 使用python为帖子数量添加最大限制

python - 关于如何根据当前 df 列创建新列的问题

python - 在 Tensorflow 中表示 3 维张量

YAML:添加链接/对外部文档的引用

c++ - 如何为 visual studio 2013 安装 YAML-cpp?

python - 如何创建 .csv 文件而不断行?

amazon-web-services - S3桶: Encountered unsupported property AccessControl

preprocessor - YAML 预处理器/宏处理器

yaml - YAML 语法 ansible playbook 中列表或键的混淆