Vấn đề nằm trong thực tế rằng YAML Resolver được thiết lập để phù hợp với nổi như sau:
Resolver.add_implicit_resolver(
u'tag:yaml.org,2002:float',
re.compile(u'''^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?
|\\.[0-9_]+(?:[eE][-+][0-9]+)?
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
|[-+]?\\.(?:inf|Inf|INF)
|\\.(?:nan|NaN|NAN))$''', re.X),
list(u'-.'))
trong khi YAML spec xác định regex cho ký hiệu khoa học như:
-? [1-9] (\. [0-9]* [1-9])? (e [-+] [1-9] [0-9]*)?
sau làm cho các dấu chấm tùy chọn, nó không phải là re.compile()
mô hình trên.
Việc kết hợp phao có thể được cố định vì vậy nó sẽ chấp nhận các giá trị dấu chấm động với một e
/E
nhưng không có dấu chấm thập phân và với số mũ không dấu (ví dụ +
ngụ ý):
import yaml
import json
import re
All = {'one':1,'low':0.000001}
jAll = json.dumps(All)
loader = yaml.SafeLoader
loader.add_implicit_resolver(
u'tag:yaml.org,2002:float',
re.compile(u'''^(?:
[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
|[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
|\\.[0-9_]+(?:[eE][-+][0-9]+)?
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
|[-+]?\\.(?:inf|Inf|INF)
|\\.(?:nan|NaN|NAN))$''', re.X),
list(u'-.'))
data = yaml.load(jAll, Loader=loader)
print 'data', data
kết quả trong:
data {'low': 1e-06, 'one': 1}
Có sự khác biệt giữa những gì JSON cho phép về số và regex trong thông số YAML 1.2 (liên quan đến dấu chấm bắt buộc trong số và e
là chữ thường). Các JSON specification là IMO rất rõ ràng ở chỗ nó không yêu cầu chấm trước khi 'e/E' cũng không có nghĩa là đòi hỏi một dấu hiệu sau khi 'e/E':
Việc thực hiện PyYAML không phù hợp nổi một phần theo thông số JSON và một phần chống lại regex và không thành công trên các con số phải hợp lệ.
ruamel.yaml (đó là phiên bản nâng cao của tôi về PyYAML), có những mẫu được cập nhật và làm việc một cách chính xác:
import ruamel.yaml
import json
All = {'one':1,'low':0.000001}
jAll = json.dumps(All)
data = ruamel.yaml.load(jAll)
print 'data', data
với sản lượng:
data {'low': 1e-06, 'one': 1}
ruamel.yaml cũng chấp nhận số '1.0e6 ', PyYAML nào cũng xem như một chuỗi.
bản sao có thể có của [Tắt ký pháp khoa học trong kết xuất python json.dumps] (http://stackoverflow.com/questions/18936554/disable-scientific-notation-in-python-json-dumps-output) – SiHa
@SiHa That có thể là một cách để tránh vấn đề này, nhưng vấn đề thực sự là YAML được coi là một superset của JSON và '1e-06' khi bạn thoát ra khỏi' cái json.dumps() '** là ** a đúng Số JSON và AFAICT cũng là số YAML chính xác. PyYAML không phân tích cú pháp chính xác. – Anthon
OK, chỉ là một suy nghĩ ... – SiHa