我正在编写一个脚本,将一系列 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/