43
Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.
Tôi thấy một API và nhiều ví dụ về cách phân tích tệp yaml nhưng còn một chuỗi thì sao?
Khi được hỏi ngày 5 tháng 5 năm 2018 lúc 5:40May 5, 2018 at 5:40
4
Đây là cách tốt nhất tôi đã thấy cho đến nay đã được chứng minh với một ví dụ:
import yaml dct = yaml.safe_load(''' name: John age: 30 automobiles: - brand: Honda type: Odyssey year: 2018 - brand: Toyota type: Sienna year: 2015 ''') assert dct['name'] == 'John' assert dct['age'] == 30 assert len(dct["automobiles"]) == 2 assert dct["automobiles"][0]["brand"] == "Honda" assert dct["automobiles"][1]["year"] == 2015Đã trả lời ngày 5 tháng 5 năm 2018 lúc 5:40May 5, 2018 at 5:40
gae123gae123gae123
7.7213 Huy hiệu vàng33 Huy hiệu bạc39 Huy hiệu Đồng3 gold badges33 silver badges39 bronze badges
3
Bạn không cần phải bọc chuỗi trong StringIO, phương thức In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 8 chấp nhận chuỗi:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2}Đã trả lời ngày 3 tháng 1 năm 2020 lúc 14:26Jan 3, 2020 at 14:26
Tomas Tomecektomas TomecekTomas Tomecek
5.7462 Huy hiệu vàng28 Huy hiệu bạc24 Huy hiệu đồng2 gold badges28 silver badges24 bronze badges
Chuyến đi tròn cơ bản của phân tích cú pháp YAML đến các đối tượng Python, sửa đổi và tạo YAML: import sys
from ruamel.yaml import YAML
inp = """\
# example
name:
# details
family: Smith # very common
given: Alice # one of the siblings
"""
yaml = YAML()
code = yaml.load(inp)
code['name']['given'] = 'Bob'
yaml.dump(code, sys.stdout)
Kết quả là: # example
name:
# details
family: Smith # very common
given: Bob # one of the siblings
với API cũ:
from __future__ import print_function import sys import ruamel.yaml inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ code = ruamel.yaml.load(inp, ruamel.yaml.RoundTripLoader) code['name']['given'] = 'Bob' ruamel.yaml.dump(code, sys.stdout, Dumper=ruamel.yaml.RoundTripDumper) # the last statement can be done less efficient in time and memory with # leaving out the end='' would cause a double newline at the end # print(ruamel.yaml.dump(code, Dumper=ruamel.yaml.RoundTripDumper), end='')
Dẫn đến
# example name: # details family: Smith # very common given: Bob # one of the siblings
Các mỏ neo thủ công YAML và các tài liệu tham khảo cũng như sự hợp nhất chính được bảo tồn. Các khóa được hợp nhất có thể được truy cập một cách minh bạch bằng cách sử dụng In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 9 và import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 0:
from ruamel.yaml import YAML inp = """\ - &CENTER {x: 1, y: 2} - &LEFT {x: 0, y: 2} - &BIG {r: 10} - &SMALL {r: 1} # All the following maps are equal: # Explicit keys - x: 1 y: 2 r: 10 label: center/big # Merge one map - <<: *CENTER r: 10 label: center/big # Merge multiple maps - <<: [*CENTER, *BIG] label: center/big # Override - <<: [*BIG, *LEFT, *SMALL] x: 1 label: center/big """ yaml = YAML() data = yaml.load(inp) assert data[7]['y'] == 2
import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 1, đó là import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 2 giống như xây dựng một khi tải tròn, hỗ trợ chèn khóa vào một vị trí cụ thể, trong khi tùy chọn thêm nhận xét:
import sys from ruamel.yaml import YAML yaml_str = """\ first_name: Art occupation: Architect # This is an occupation comment about: Art Vandelay is a fictional character that George invents... """ yaml = YAML() data = yaml.load(yaml_str) data.insert(1, 'last name', 'Vandelay', comment="new key") yaml.dump(data, sys.stdout)
gives:
first_name: Art last name: Vandelay # new key occupation: Architect # This is an occupation comment about: Art Vandelay is a fictional character that George invents...
Xin lưu ý rằng nhận xét được căn chỉnh với hàng xóm của nó (nếu có).
Trên đây được lấy cảm hứng từ một câu hỏi được đăng bởi Demux trên Stackoverflow.
Theo mặc định import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 3 chỉ ra với hai vị trí theo kiểu khối, cho cả ánh xạ và trình tự. Đối với các chuỗi, phần thụt được tính đến đầu vô hướng, với dấu gạch ngang chiếm vị trí đầu tiên của không gian bị thụt vào.
Bạn có thể thay đổi thụt mặc định này bằng cách ví dụ: Sử dụng import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 4:
import sys from ruamel.yaml import YAML d = dict(a=dict(b=2),c=[3, 4]) yaml = YAML() yaml.dump(d, sys.stdout) print('0123456789') yaml = YAML() yaml.indent(mapping=4, sequence=6, offset=3) yaml.dump(d, sys.stdout) print('0123456789')
giving:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 0
Nếu một chuỗi khối hoặc ánh xạ khối là phần tử của một chuỗi, theo mặc định, được hiển thị ký hiệu nhỏ gọn. Điều này có nghĩa là dấu gạch ngang của chuỗi cha mẹ của người Viking nằm trên cùng một dòng với phần tử đầu tiên được resp. Cặp khóa/giá trị đầu tiên của bộ sưu tập trẻ em.
Nếu bạn muốn một hoặc cả hai điều này (trình tự trong chuỗi, ánh xạ trong chuỗi) sẽ bắt đầu trên dòng tiếp theo sử dụng import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 5:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 1
giving:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 2
Chương trình sau đây sử dụng ba bãi chứa cùng một dữ liệu, dẫn đến một luồng với ba tài liệu:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 3
đưa ra như đầu ra:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 4
Ví dụ biến đổi, trong tài liệu cuối cùng, được lấy cảm hứng từ một câu hỏi được đăng bởi * nowox * trên stackoverflow.
Đầu ra của import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 6 dưới dạng chuỗi
Tính năng bị lạm dụng nhiều nhất trên mạng của API cũ không cung cấp tham số luồng (thứ hai) cho một trong các biến thể import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 6, để có được biểu diễn chuỗi nguyên khối của luồng trở lại.
Ngoài việc không hiệu quả và chậm, những người sử dụng điều này không nhận ra rằng import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 8 giúp bạn có thêm một dòng, trống rỗng, sau import sys from ruamel.yaml import YAML inp = """\ # example name: # details family: Smith # very common given: Alice # one of the siblings """ yaml = YAML() code = yaml.load(inp) code['name']['given'] = 'Bob' yaml.dump(code, sys.stdout) 9.
Câu hỏi thực sự là tại sao chức năng này, điều này hiếm khi thực sự cần thiết, có sẵn trong API cũ (và trong Pyyaml) ngay từ đầu. Một lời giải thích mà bạn nhận được bằng cách nhìn vào những gì ai đó sẽ cần làm để làm cho điều này có sẵn nếu nó đã có ở đó. Ngoài việc phân lớp # example name: # details family: Smith # very common given: Bob # one of the siblings 0 và cung cấp một phương thức # example name: # details family: Smith # very common given: Bob # one of the siblings 1 mới, sẽ có mười dòng, một trăm dòng khác, về cơ bản là toàn bộ tệp # example name: # details family: Smith # very common given: Bob # one of the siblings 2, sẽ cần phải được sao chép và sử dụng trình tự điều chỉnh này.hundred lines, essentially the whole # example name: # details family: Smith # very common given: Bob # one of the siblings 2 file, would need to be copied and to make use of this serializer.
Thực tế là người ta thường nên thực hiện # example name: # details family: Smith # very common given: Bob # one of the siblings 3 và loại bỏ 90% các trường hợp để trả lại chuỗi, và tất cả các yaml sau xử lý, trước khi viết để phát trực tuyến, có thể được xử lý bằng cách sử dụng tham số # example name: # details family: Smith # very common given: Bob # one of the siblings 4 của Dump, có thể để xử lý hầu hết các phần còn lại. Nhưng điều đó cũng dễ dàng hơn nhiều trong API mới để cung cấp đầu ra YAML như một chuỗi nếu bạn thực sự cần phải có nó (hoặc nghĩ rằng bạn làm):
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 5
Với khoảng một phần mười của các dòng cần thiết cho giao diện cũ, bạn có thể một lần nữa làm:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 6
thay vì:
In [1]: yaml.safe_load("{1: 2}") Out[1]: {1: 2} 7