Định dạng danh sách kết xuất python yaml

Python thường được bán trên thị trường dưới dạng ngôn ngữ có pin vì nó đi kèm với hầu hết mọi thứ bạn mong đợi từ một ngôn ngữ lập trình. Tuyên bố này gần như đúng, vì thư viện chuẩn và các mô-đun bên ngoài đáp ứng nhiều nhu cầu lập trình. Tuy nhiên, Python thiếu hỗ trợ tích hợp cho định dạng dữ liệu YAML, thường được sử dụng để cấu hình và tuần tự hóa, mặc dù có sự tương đồng rõ ràng giữa hai ngôn ngữ

Trong hướng dẫn này, bạn sẽ học cách làm việc với YAML trong Python bằng các thư viện bên thứ ba có sẵn, tập trung vào PyYAML. Nếu bạn là người mới sử dụng YAML hoặc chưa sử dụng nó trong một thời gian, thì bạn sẽ có cơ hội tham gia một khóa học cấp tốc trước khi tìm hiểu sâu hơn về chủ đề này

Trong hướng dẫn này, bạn sẽ học cách

  • Đọc và viết tài liệu YAML bằng Python
  • Tuần tự hóa các loại dữ liệu tùy chỉnh và tích hợp sẵn của Python thành YAML
  • Đọc tài liệu YAML một cách an toàn từ các nguồn không đáng tin cậy
  • Kiểm soát phân tích tài liệu YAML ở cấp độ thấp hơn

Sau đó, bạn sẽ tìm hiểu về các tính năng nâng cao, có khả năng gây nguy hiểm của YAML và cách bảo vệ bạn khỏi chúng. Để phân tích cú pháp YAML ở mức thấp, bạn sẽ xây dựng công cụ đánh dấu cú pháp và bản xem trước tương tác trong HTML. Cuối cùng, bạn sẽ tận dụng các thẻ YAML tùy chỉnh để mở rộng cú pháp của định dạng dữ liệu

Để tận dụng tối đa hướng dẫn này, bạn nên làm quen với lập trình hướng đối tượng trong Python và biết cách tạo lớp. Nếu bạn đã sẵn sàng tham gia, thì bạn có thể nhấp vào liên kết bên dưới để lấy mã nguồn cho các ví dụ mà bạn sẽ viết mã trong hướng dẫn này

Nhận mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để làm việc với YAML trong Python

Tham gia một khóa học cấp tốc trong YAML

Trong phần này, bạn sẽ tìm hiểu các thông tin cơ bản về YAML, bao gồm cách sử dụng, cú pháp và một số tính năng độc đáo và mạnh mẽ của nó. Nếu bạn đã từng làm việc với YAML trước đây thì bạn có thể bỏ qua và tiếp tục đọc phần tiếp theo, bao gồm việc sử dụng YAML trong Python

Loại bỏ các quảng cáo

Bối cảnh lịch sử

YAML, vần với lạc đà, là từ viết tắt đệ quy viết tắt của YAML Ain't Markup Language bởi vì nó không phải là ngôn ngữ đánh dấu. Thật thú vị, bản nháp ban đầu cho đặc tả YAML đã xác định ngôn ngữ là Yet Another Markup Language, nhưng sau đó, từ viết tắt hiện tại đã được sử dụng để mô tả chính xác hơn mục đích của ngôn ngữ

Một ngôn ngữ đánh dấu thực tế, chẳng hạn như Markdown hoặc HTML, cho phép bạn chú thích văn bản với các hướng dẫn định dạng hoặc xử lý xen kẽ với nội dung của bạn. Do đó, các ngôn ngữ đánh dấu chủ yếu liên quan đến các tài liệu văn bản, trong khi YAML là một định dạng tuần tự hóa dữ liệu tích hợp tốt với các loại dữ liệu phổ biến có nguồn gốc từ nhiều ngôn ngữ lập trình. Không có văn bản vốn có trong YAML, chỉ có dữ liệu để thể hiện

YAML ban đầu được dùng để đơn giản hóa Ngôn ngữ đánh dấu mở rộng [XML], nhưng trên thực tế, nó có nhiều điểm chung hơn với Ký hiệu đối tượng JavaScript [JSON]. Trên thực tế, đó là một siêu bộ JSON

Mặc dù XML ban đầu được thiết kế để trở thành ngôn ngữ kim loại để tạo ngôn ngữ đánh dấu cho tài liệu, mọi người đã nhanh chóng sử dụng nó làm định dạng tuần tự hóa dữ liệu tiêu chuẩn. Cú pháp giống như HTML của dấu ngoặc nhọn làm cho XML trông quen thuộc. Đột nhiên, mọi người đều muốn sử dụng XML làm định dạng cấu hình, tính bền vững hoặc thông báo của họ

Là đứa trẻ đầu tiên trong khối, XML đã thống trị hiện trường trong nhiều năm. Nó đã trở thành một định dạng trao đổi dữ liệu trưởng thành và đáng tin cậy, đồng thời giúp hình thành các khái niệm mới như xây dựng các ứng dụng web tương tác. Xét cho cùng, chữ X trong AJAX, một kỹ thuật lấy dữ liệu từ máy chủ mà không cần tải lại trang, không gì khác chính là XML

Trớ trêu thay, chính AJAX cuối cùng đã dẫn đến sự suy giảm mức độ phổ biến của XML. Cú pháp XML dài dòng, phức tạp và dư thừa đã lãng phí rất nhiều băng thông khi dữ liệu được gửi qua mạng. Phân tích cú pháp tài liệu XML trong JavaScript chậm và tẻ nhạt do mô hình đối tượng tài liệu cố định [DOM] của XML, không khớp với mô hình dữ liệu của ứng dụng. Cộng đồng cuối cùng đã thừa nhận rằng họ đã sử dụng sai công cụ cho công việc

Đó là khi JSON vào bức tranh. Nó được xây dựng từ đầu với ý tưởng tuần tự hóa dữ liệu. Các trình duyệt web có thể phân tích nó một cách dễ dàng vì JSON là một tập hợp con của JavaScript mà chúng đã hỗ trợ. Cú pháp tối giản của JSON không chỉ hấp dẫn các nhà phát triển mà còn giúp việc chuyển sang các nền tảng khác dễ dàng hơn so với XML. Cho đến ngày nay, JSON vẫn là định dạng trao đổi dữ liệu văn bản mỏng nhất, nhanh nhất và linh hoạt nhất trên Internet

YAML ra đời cùng năm với JSON và hoàn toàn trùng hợp, nó gần như là một siêu bộ hoàn chỉnh của JSON ở cấp độ cú pháp và ngữ nghĩa. Bắt đầu từ YAML 1. 2, định dạng này chính thức trở thành một siêu bộ nghiêm ngặt của JSON, nghĩa là mọi tài liệu JSON hợp lệ cũng là một tài liệu YAML

Tuy nhiên, trên thực tế, hai định dạng trông khác nhau, vì đặc tả YAML nhấn mạnh hơn vào khả năng đọc của con người bằng cách thêm nhiều đường cú pháp và tính năng hơn trên JSON. Do đó, YAML phù hợp hơn với các tệp cấu hình được chỉnh sửa thủ công hơn là lớp vận chuyển

So sánh với XML và JSON

Nếu bạn đã quen thuộc với XML hoặc JSON, thì bạn có thể tự hỏi YAML mang lại điều gì cho bảng. Cả ba đều là các định dạng trao đổi dữ liệu chính, chia sẻ một số tính năng chồng chéo. Ví dụ: tất cả chúng đều dựa trên văn bản và ít nhiều có thể đọc được bằng con người. Đồng thời, chúng khác nhau ở nhiều khía cạnh mà bạn sẽ tìm hiểu tiếp theo

Ghi chú. Có các định dạng dữ liệu văn bản khác, ít phổ biến hơn như TOML, mà hệ thống xây dựng mới trong Python dựa trên. Hiện tại, chỉ các công cụ quản lý phụ thuộc và đóng gói bên ngoài như Thơ mới có thể đọc TOML, nhưng Python 3. 11 sẽ sớm có bộ phân tích cú pháp TOML trong thư viện chuẩn

Các định dạng tuần tự hóa dữ liệu nhị phân phổ biến mà bạn tìm thấy trong tự nhiên bao gồm Bộ đệm giao thức của Google và Avro của Apache

Bây giờ hãy xem một tài liệu mẫu được thể hiện ở cả ba định dạng dữ liệu nhưng đại diện cho cùng một người. Bạn có thể nhấp để mở rộng các phần có thể thu gọn và hiển thị dữ liệu được đăng nhiều kỳ ở các định dạng đó

XMLHiển thị/Ẩn



    1969-12-31
    true
    
        
             
        
    

JSONHiển thị/Ẩn

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}

YAMLHiển thị/Ẩn

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe

Thoạt nhìn, XML dường như có cú pháp đáng sợ nhất, gây ra nhiều tiếng ồn. JSON cải thiện đáng kể tình hình về mặt đơn giản, nhưng nó vẫn chôn vùi thông tin bên dưới các dấu phân cách bắt buộc. Mặt khác, YAML sử dụng thụt lề khối kiểu Python để xác định cấu trúc, làm cho nó trông rõ ràng và đơn giản. Nhược điểm là bạn không thể thu gọn khoảng trắng để giảm dung lượng khi truyền tin nhắn qua dây

Ghi chú. JSON là định dạng dữ liệu duy nhất không hỗ trợ nhận xét. Chúng đã bị xóa khỏi đặc điểm kỹ thuật nhằm mục đích đơn giản hóa trình phân tích cú pháp và ngăn mọi người lạm dụng chúng để nhận các hướng dẫn xử lý tùy chỉnh

Đây là một so sánh hơi chủ quan về XML, JSON và YAML để cung cấp cho bạn ý tưởng về cách chúng xếp chồng lên nhau như các định dạng trao đổi dữ liệu ngày nay

XMLJSONYAMLAáp dụng và hỗ trợ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐Khả năng đọc⭐⭐⭐⭐⭐⭐⭐⭐⭐Tốc độ đọc và ghi⭐⭐⭐⭐⭐⭐⭐Kích thước tệp⭐⭐⭐⭐⭐⭐

Khi bạn xem Google Xu hướng để theo dõi sở thích trong ba cụm từ tìm kiếm, thì bạn sẽ kết luận rằng JSON là người chiến thắng hiện tại. Tuy nhiên, XML không thua xa, với YAML thu hút ít sự quan tâm nhất. Ngoài ra, có vẻ như mức độ phổ biến của XML đã giảm dần kể từ khi Google bắt đầu thu thập dữ liệu

Ghi chú. Trong số ba định dạng này, XML và JSON là những định dạng duy nhất mà Python hỗ trợ ngay lập tức, trong khi nếu bạn muốn làm việc với YAML, thì bạn phải tìm và cài đặt thư viện bên thứ ba tương ứng. Mặc dù vậy, Python không phải là ngôn ngữ duy nhất hỗ trợ XML và JSON tốt hơn YAML. Bạn có thể tìm thấy xu hướng này trên các ngôn ngữ lập trình

YAML được cho là dễ nhìn nhất, vì tính dễ đọc luôn là một trong những nguyên tắc cốt lõi của nó, nhưng JSON cũng không tệ. Một số thậm chí có thể thấy JSON ít lộn xộn và ồn ào hơn do cú pháp tối giản của nó và giống với các danh sách và từ điển Python. XML là dài dòng nhất, vì nó yêu cầu gói mọi mẩu thông tin trong một cặp thẻ mở và thẻ đóng

Trong Python, hiệu suất khi làm việc với các định dạng dữ liệu này sẽ khác nhau và sẽ rất nhạy cảm với cách triển khai mà bạn chọn. Việc triển khai Python thuần túy sẽ luôn thua thư viện C đã biên dịch. In addition to this, using different XML processing models—[DOM, SAX, or StAX]—will also impact performance

Implementations aside, YAML’s versatile, liberal, and complex syntax makes it by far the slowest to parse and serialize. On the other side of the spectrum, you’ll find JSON, whose grammar can fit on a business card. In contrast, YAML’s own grammar documentation claims that creating a fully compliant parser has proven almost impossible

Fun Fact. The official yaml. org website is written as a valid YAML document

When it comes to document size, JSON is a clear winner again. While the extra quotation marks, commas, and curly brackets take up valuable space, you can remove all the whitespace between the individual elements. You can do the same with XML documents, but it won’t overcome the overhead of the opening and closing tags. YAML sits somewhere in the middle by having a comparatively medium size

Historically, XML has had the best support across a wide range of technologies. JSON is an unbeatable all-around interchange format for transferring data on the Internet. So, who uses YAML and why?

Loại bỏ các quảng cáo

Practical Uses of YAML

As noted earlier, YAML is mostly praised for its readability, which makes it perfect for storing all kinds of configuration data in a human-readable format. It became especially popular among DevOps engineers, who’ve built automation tools around it. A few examples of such tools include

  • Ansible. Uses YAML to describe the desired state of the remote infrastructure, manage the configuration, and orchestrate IT processes
  • Docker Compose. Uses YAML to describe the microservices comprising your Dockerized application
  • Kubernetes. Uses YAML to define various objects in a computer cluster to orchestrate and manage

Apart from that, some general-purpose tools, libraries, and services give you the option to configure them through YAML, which you may find more convenient than other data formats. For example, platforms like CircleCI and GitHub frequently turn to YAML to define continuous integration, deployment, and delivery [CI/CD] pipelines. The OpenAPI Specification allows for code stub generation based on a YAML description of RESTful APIs

Ghi chú. The documentation for Python’s logging framework mentions YAML despite the fact that the language doesn’t support YAML natively

Maybe you’ll decide to adopt YAML in your future project after completing this tutorial

YAML Syntax

YAML draws heavy inspiration from other data formats and languages that you might have heard of before. Perhaps the most striking and familiar element of YAML’s syntax is its block indentation, which resembles Python code. The leading whitespace on each line defines the scope of a block, eliminating the need for any special characters or tags to denote where it begins or ends

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly

This sample document defines a family tree with

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
7 as the root element, whose immediate child is the
{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
8 element, which has two children with the
{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
9 attribute on the lowest level in the tree. You can think of each element as an opening statement followed by a colon [
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
0] in Python

Note. The YAML specification forbids using tabs for indentation and considers their use a syntax error. This coincides with Python’s PEP 8 recommendation about preferring spaces over tabs

At the same time, YAML lets you leverage an alternative inline-block syntax borrowed from JSON. You can rewrite the same document in the following way

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}

Notice how you can mix the indented and inline blocks in one document. Also, you’re free to enclose both the attributes and their values in single quotes [

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
1] or double quotes [
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
2] if you want to. Doing so enables one of two interpolation methods of the special character sequences, which are otherwise escaped with another backslash [
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
3] for you. Below, you’ll find Python equivalents alongside the YAML

YAMLPythonDescription

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
4
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
5Unquoted strings are parsed literally so that escape sequences like
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
6 become
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
7.
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
8
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
9Single-quoted strings only interpolate the double apostrophe [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
00], but not the traditional escape sequences like
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
6.
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
02
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
4Double-quoted [
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
2] strings interpolate escape sequences like
recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
6,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
06, or
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
07, known from the C programming language, but not the double apostrophe [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
00]

Don’t worry if that looks confusing. You’ll want to specify unquoted string literals in YAML for the most part, anyway. One notable exception would be declaring a string that the parser could misinterpret as the wrong data type. For example,

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
09 written without any quotation marks might be treated as a Python Boolean

The three fundamental data structures in YAML are essentially the same as in Perl, which was once a popular scripting language. They’re the following

  1. Scalars. Simple values like numbers, strings, or Booleans
  2. Arrays. Sequences of scalars or other collections
  3. Hashes. Associative arrays, also known as maps, dictionaries, objects, or records comprised of key-value pairs

You can define a YAML scalar similarly to a corresponding Python literal. Here are a few examples

Data TypeYAMLNull

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
10,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
11Boolean
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
12,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
13 [Before YAML 1. 2.
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
14,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
15,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
16,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
17]Integer
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
18,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
19,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
20,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
21 [Before YAML 1. 2.
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
22]Floating-Point
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
23,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
24,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
25,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
26String
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
27Date and Time
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
28,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
29,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
30

You can write reserved words in YAML in lowercase [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
10], uppercase [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
32], or title case [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
33] to parse them into the desired data type. Any other case variant of such words will be treated as plain text. The
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
10 constant or its tilde [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
11] alias lets you explicitly state the lack of a value, but you can also leave the value blank for the same effect

Note. This implicit typing in YAML seems convenient, but it’s like playing with fire, and it can cause serious problems in edge cases. As a result, the YAML 1. 2 specification dropped support for some built-in literals like

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
14 and
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
15

Sequences in YAML are just like Python lists or JSON arrays. They use the standard square bracket syntax [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
38] in the inline-block mode or the leading dashes [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
39] at the start of each line when they’re block indented

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
8

You can keep your list items at the same indentation level as their property name or add more indentation if that improves readability for you

Finally, YAML has hashes analogous to Python dicts or JavaScript objects. They’re made of keys, also known as attribute or property names, followed by a colon [

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
0] and a value. You’ve seen a few examples of YAML hashes in this section already, but here’s a more involved one

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
0

You’ve just defined a person, John Doe, who’s married to Jane Smith and has two children, Bobby and Molly. Notice how the list of children contains anonymous objects, unlike, for example, the spouse defined under a property named

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
41. When anonymous or unnamed objects appear as list items, you can recognize them by their properties, which are aligned with an opening dash character [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
39]

Ghi chú. Tên thuộc tính trong YAML khá linh hoạt, vì chúng có thể chứa các ký tự khoảng trắng và trải rộng trên nhiều dòng. Hơn nữa, bạn không bị giới hạn chỉ sử dụng các chuỗi. Không giống như JSON, nhưng tương tự như từ điển Python, hàm băm YAML cho phép bạn sử dụng hầu hết mọi loại dữ liệu cho một khóa

Đương nhiên, bạn mới chỉ vạch ra bề nổi ở đây, vì YAML có rất nhiều tính năng nâng cao hơn để cung cấp. Bạn sẽ tìm hiểu về một số trong số họ bây giờ

Loại bỏ các quảng cáo

Tính năng độc đáo

Trong phần này, bạn sẽ xem một số tính năng độc đáo nhất của YAML, bao gồm

  • Loại dữ liệu
  • thẻ
  • Neo và bí danh
  • thuộc tính hợp nhất
  • Phong cách dòng chảy và khối
  • Luồng nhiều tài liệu

Mặc dù XML là tất cả về văn bản và JSON kế thừa một số kiểu dữ liệu của JavaScript, tính năng xác định của YAML là tích hợp chặt chẽ với các hệ thống kiểu của ngôn ngữ lập trình hiện đại. Ví dụ: bạn có thể sử dụng YAML để tuần tự hóa và giải tuần tự hóa các loại dữ liệu được tích hợp trong Python, chẳng hạn như ngày và giờ

YAMLPython

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
30
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
44
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
28
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
46
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
47
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
48
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
49
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
50

YAML hiểu các định dạng ngày và giờ khác nhau, bao gồm tiêu chuẩn ISO 8601 và có thể hoạt động với các múi giờ tùy chọn. Dấu thời gian như 23. 59. 59 được deserialized thành số giây trôi qua kể từ nửa đêm

Để giải quyết sự mơ hồ tiềm ẩn, bạn có thể truyền giá trị cho các loại dữ liệu cụ thể bằng cách sử dụng thẻ YAML, bắt đầu bằng dấu chấm than kép [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
51]. Có một vài thẻ độc lập với ngôn ngữ nhưng các trình phân tích cú pháp khác nhau có thể cung cấp các tiện ích mở rộng bổ sung chỉ liên quan đến ngôn ngữ lập trình của bạn. Ví dụ: thư viện mà bạn sẽ sử dụng sau này cho phép bạn chuyển đổi các giá trị thành các loại Python gốc và thậm chí tuần tự hóa các lớp tùy chỉnh của bạn

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
2

Việc sử dụng thẻ

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
52 bên cạnh đối tượng ngày làm cho YAML coi nó như một chuỗi thông thường. Dấu chấm hỏi [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
53] biểu thị khóa ánh xạ trong YAML. They’re usually unnecessary but can help you define a compound key from another collection or a key that contains reserved characters. In this case, you want to define blank keys to create a set data structure, which is equivalent to a mapping without the keys

Moreover, you can use the

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
54 tag to embed Base64-encoded binary files such as images or other resources, which will become instances of
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
55 in Python. The tags prefixed with
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
56 are provided by PyYAML

The YAML document above would translate into the following Python dictionary

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}

Notice how, with the help of YAML tags, the parser turned property values into various Python data types, including a string, a set, a bytes object, a tuple, a complex number, and even a custom class instance

Other powerful features of YAML are anchors and aliases, which let you define an element once and then refer to it many times within the same document. Potential use cases include

  • Reusing the shipping address for invoicing
  • Rotating meals in a meal plan
  • Referencing exercises in a training program

To declare an anchor, which you can think of as a named variable, you’d use the ampersand [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
57] symbol, while to dereference that anchor later on, you’d use the asterisk [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
58] symbol

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank

Tại đây, bạn đã tạo một kế hoạch tập luyện từ các bài tập mà bạn đã xác định trước đó, lặp lại chúng trong các thói quen hàng ngày khác nhau. Ngoài ra, thuộc tính

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
59 thể hiện một ví dụ về tham chiếu vòng. Thuộc tính này là một dãy mà phần tử duy nhất là chính dãy đó. Nói cách khác,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
60 giống như
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
59

Ghi chú. Không giống như XML và JSON thuần túy, chỉ có thể biểu thị các cấu trúc phân cấp dạng cây với một phần tử gốc duy nhất, YAML cũng cho phép mô tả các cấu trúc đồ thị có hướng bằng các chu kỳ đệ quy. Tuy nhiên, có thể tham chiếu chéo trong XML và JSON với sự trợ giúp của các tiện ích mở rộng hoặc phương ngữ tùy chỉnh

Bạn cũng có thể hợp nhất [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
62] hoặc ghi đè các thuộc tính được xác định ở nơi khác bằng cách kết hợp hai hoặc nhiều đối tượng

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
0

Đối tượng

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
63 kế thừa các thuộc tính của
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
64 và
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
65 đồng thời thêm một thuộc tính mới,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
66 và thay đổi giá trị của
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
67

Vô hướng trong YAML hỗ trợ kiểu dòng hoặc kiểu khối, cung cấp cho bạn các mức kiểm soát khác nhau đối với việc xử lý dòng mới trong chuỗi nhiều dòng. Vô hướng luồng có thể bắt đầu trên cùng một dòng với tên thuộc tính của chúng và có thể trải rộng trên nhiều dòng

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
1

Trong trường hợp như vậy, khoảng trắng ở đầu và cuối của mỗi dòng sẽ luôn được xếp vào một khoảng trắng duy nhất, biến các đoạn văn thành các dòng. Điều này hoạt động hơi giống HTML hoặc Markdown, dẫn đến đoạn văn bản sau

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
2

Và, trong trường hợp bạn đang thắc mắc, Lorem ipsum là một văn bản giữ chỗ phổ biến được sử dụng trong văn bản và thiết kế web để lấp đầy khoảng trống có sẵn. Nó không mang bất kỳ ý nghĩa nào, vì nó cố tình vô nghĩa và được viết bằng tiếng Latinh không phù hợp để giúp bạn tập trung vào hình thức hơn là nội dung

Trái ngược với vô hướng dòng chảy, vô hướng khối cho phép thay đổi cách xử lý các dòng mới, dòng mới theo sau hoặc thụt đầu dòng. Ví dụ: chỉ báo đường ống [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
68] được đặt ngay sau tên thuộc tính sẽ giữ nguyên các dòng mới theo nghĩa đen, điều này có thể hữu ích cho việc nhúng các tập lệnh shell vào tệp YAML của bạn

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
3

Tài liệu YAML ở trên định nghĩa một thuộc tính có tên là

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
69, chứa một đoạn mã Python ngắn bao gồm một vài dòng mã. Nếu không có chỉ báo đường ống, trình phân tích cú pháp YAML sẽ coi các dòng sau đây là các phần tử lồng nhau thay vì toàn bộ. Ansible là một ví dụ đáng chú ý tận dụng tính năng này của YAML

Nếu bạn chỉ muốn gấp các dòng có thụt đầu dòng được xác định bởi dòng đầu tiên trong đoạn văn, thì hãy sử dụng dấu lớn hơn [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
70] chỉ báo

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
4

Điều này sẽ tạo ra đầu ra sau

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
5

Cuối cùng, bạn có thể lưu trữ nhiều tài liệu YAML trong một tệp duy nhất được phân tách bằng dấu gạch ngang ba lần [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
71]. Bạn có thể tùy chọn sử dụng dấu ba chấm [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
72] để đánh dấu phần cuối của mỗi tài liệu

Loại bỏ các quảng cáo

Bắt đầu với YAML trong Python

Như bạn đã học trong phần giới thiệu, làm việc với YAML trong Python cần thêm một vài bước vì ngôn ngữ này không hỗ trợ định dạng dữ liệu này ngay lập tức. Bạn sẽ cần một thư viện của bên thứ ba để tuần tự hóa các đối tượng Python thành YAML và ngược lại

Ngoài ra, bạn có thể thấy hữu ích khi cài đặt các công cụ dòng lệnh này với pip vào môi trường ảo của mình để trợ giúp gỡ lỗi

  • yamllint. Một kẻ nói dối cho YAML, có thể kiểm tra cú pháp và hơn thế nữa
  • yq. Bộ xử lý YAML dòng lệnh dựa trên jq, để lọc dữ liệu
  • nhút nhát. Một bộ xử lý YAML dòng lệnh thay thế

Đây là tất cả các công cụ Python, nhưng cũng có một triển khai Go rộng rãi của yq, có giao diện dòng lệnh hơi khác. Nếu bạn không thể hoặc không muốn cài đặt các chương trình đó, thì bạn luôn có thể sử dụng một trong các công cụ có sẵn trực tuyến, chẳng hạn như

  • Trình phân tích cú pháp YAML
  • Trình định dạng YAML
  • Trình xác thực YAML

Lưu ý rằng bạn sẽ chỉ cần một số công cụ đó trong tiểu mục sau, trong khi bạn sẽ bắt đầu làm quen với YAML bằng Python thuần túy trong phần còn lại của hướng dẫn này

Tuần tự hóa các tài liệu YAML dưới dạng JSON

Mặc dù Python không cung cấp trình phân tích cú pháp YAML hoặc trình tuần tự hóa chuyên dụng, nhưng bạn có thể khắc phục vấn đề này ở một mức độ nào đó với sự trợ giúp của mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
73 tích hợp. Xét cho cùng, bạn đã biết rằng YAML là một siêu tập hợp của JSON, vì vậy bạn có thể kết xuất dữ liệu của mình sang định dạng JSON thông thường trong Python và mong đợi các trình phân tích cú pháp YAML bên ngoài chấp nhận nó

First, make a sample Python script to print out JSON on the standard output

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
6

Bạn tạo một từ điển và sau đó gọi

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
74 trên đó để kết xuất một chuỗi. Tham số
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
75 chỉ định một hàm để gọi khi Python không thể tuần tự hóa một đối tượng thành JSON, đó là trường hợp của ngày sinh trong ví dụ này. Hàm
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
76 tích hợp sẽ chuyển đổi đối tượng
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
77 thành chuỗi ISO 8601

Bây giờ, hãy chạy tập lệnh của bạn và cung cấp đầu ra của nó cho một trong các trình phân tích cú pháp YAML dòng lệnh đã đề cập trước đó, chẳng hạn như

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
78 hoặc
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
79, thông qua đường dẫn Unix [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
68]

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
7

Tốt đẹp. Cả hai trình phân tích cú pháp đã định dạng dữ liệu của bạn ở định dạng YAML chính tắc hơn mà không phàn nàn. Tuy nhiên, vì

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
78 là một trình bao bọc mỏng xung quanh
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
82 của JSON, nên bạn phải yêu cầu nó thực hiện chuyển mã với tùy chọn
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
83 và một dấu chấm ở cuối dưới dạng biểu thức lọc. Ngoài ra, hãy lưu ý một chút khác biệt trong kết quả thụt đầu dòng giữa
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
78 và
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
79

Ghi chú. Để sử dụng

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
78, trước tiên bạn phải cài đặt
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
82 trong hệ điều hành của mình nếu nó chưa có sẵn

Được rồi, điều đó giống như gian lận và nó chỉ hoạt động theo một cách, vì bạn không thể đọc lại tệp YAML vào Python bằng mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
73. Rất may, có nhiều cách để làm điều đó

Cài đặt thư viện PyYAML

Cho đến nay, thư viện YAML bên thứ ba phổ biến nhất của Python là PyYAML, đây luôn là một trong những gói hàng đầu được tải xuống từ PyPI. Nó có giao diện trông hơi giống với mô-đun JSON tích hợp, nó được duy trì tích cực và nó được trang web YAML chính thức hỗ trợ, liệt kê nó cùng với một số ứng cử viên ít phổ biến hơn

Để cài đặt PyYAML vào môi trường ảo đang hoạt động của bạn, hãy nhập lệnh sau trong thiết bị đầu cuối của bạn

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
8

Thư viện độc lập và không yêu cầu bất kỳ phụ thuộc nào nữa vì nó được viết bằng Python thuần túy. Tuy nhiên, hầu hết các bản phân phối đều gói một liên kết C đã biên dịch cho thư viện LibYAML, giúp PyYAML chạy nhanh hơn nhiều. Để xác nhận xem cài đặt PyYAML của bạn có liên kết C hay không, hãy mở trình thông dịch Python tương tác và chạy đoạn mã này

>>>

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
9

Mặc dù PyYAML là tên của thư viện bạn đã cài đặt, nhưng bạn sẽ nhập gói

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
89 bằng mã Python. Ngoài ra, lưu ý rằng bạn cần yêu cầu rõ ràng rằng PyYAML tận dụng thư viện C được chia sẻ nhanh hơn đáng kể, nếu không, nó sẽ trở về mặc định là Python thuần túy. Đọc tiếp để tìm hiểu cách thay đổi hành vi mặc định này

Mặc dù phổ biến nhưng PyYAML có một số nhược điểm. Ví dụ: nếu bạn cần sử dụng các tính năng được giới thiệu trong YAML 1. 2, chẳng hạn như tuân thủ JSON đầy đủ hoặc nghĩa đen an toàn hơn, thì tốt hơn hết bạn nên sử dụng ruamel. thư viện yaml, bắt nguồn từ phiên bản PyYAML cũ hơn. Như một phần thưởng, nó có thể thực hiện phân tích cú pháp khứ hồi để giữ lại các nhận xét và định dạng ban đầu khi cần

Mặt khác, nếu an toàn loại là mối quan tâm chính của bạn hoặc bạn muốn xác thực các tài liệu YAML dựa trên một lược đồ, thì hãy xem StrictYAML, nó cố ý hạn chế đặc tả YAML bằng cách bỏ qua các tính năng rủi ro nhất của nó. Chỉ cần lưu ý rằng nó sẽ không chạy nhanh như hai thư viện kia

Hiện tại, bạn sẽ gắn bó với PyYAML trong phần còn lại của hướng dẫn này vì nó là lựa chọn tiêu chuẩn cho hầu hết các dự án Python. Lưu ý rằng các công cụ được liệt kê trước đó—yamllint, yq và shyaml—sử dụng PyYAML dưới bề mặt

Loại bỏ các quảng cáo

Đọc và viết tài liệu YAML đầu tiên của bạn

Giả sử bạn muốn đọc và phân tích cú pháp một email giả định đã được đăng tuần tự sang định dạng YAML và được lưu trữ trong một biến chuỗi trong Python

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
0

Cách nhanh nhất để giải tuần tự hóa một đoạn YAML như vậy vào từ điển Python là thông qua hàm

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
90

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
1

Gọi

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
91 hiện là cách được khuyến nghị để xử lý nội dung nhận được từ các nguồn không đáng tin cậy, có thể chứa mã độc. YAML có một cú pháp rõ ràng với đầy đủ các tính năng tiện lợi, điều này không may mở ra một loạt các lỗ hổng. Bạn sẽ tìm hiểu thêm về cách khai thác điểm yếu của YAML sau

Ghi chú. Trước phiên bản 6. 0 của thư viện PyYAML, cách phân tích cú pháp tài liệu YAML mặc định luôn là hàm

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
92, được mặc định sử dụng trình phân tích cú pháp không an toàn. Với bản phát hành mới nhất, bạn vẫn có thể sử dụng chức năng này nhưng nó yêu cầu bạn chỉ định rõ ràng một lớp trình tải cụ thể làm tham số thứ hai

Introducing this additional parameter was a breaking change that resulted in many complaints from people maintaining software dependent on PyYAML. Vẫn còn một vấn đề được ghim trên kho lưu trữ GitHub của thư viện về sự không tương thích ngược này

Tại thời điểm viết hướng dẫn này, tài liệu chính thức của PyYAML cũng như các chuỗi tài liệu đi kèm chưa được cập nhật để phản ánh cơ sở mã hiện tại và chúng chứa các ví dụ không còn hoạt động nữa

Hàm

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
91 là một trong một số hàm tốc ký gói gọn việc sử dụng các lớp trình tải YAML khác nhau dưới mui xe. Trong trường hợp này, lệnh gọi hàm đơn lẻ đó chuyển thành đoạn mã tương đương nhưng rõ ràng hơn sau đây

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
2

Một điều cần nhớ khi sử dụng các hàm tốc ký là chúng mã hóa cứng việc triển khai Python thuần túy. Nếu bạn muốn sử dụng triển khai C nhanh hơn, thì bạn phải tự viết một chút mã soạn sẵn

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
3

Trước tiên, bạn thử nhập một trong các lớp trình tải có tiền tố là chữ C để biểu thị việc sử dụng liên kết thư viện C. Nếu thất bại, thì bạn nhập một lớp tương ứng được triển khai trong Python. Thật không may, điều này làm cho mã của bạn trông dài dòng hơn và ngăn bạn sử dụng các chức năng phím tắt được đề cập

Ghi chú. Nếu YAML của bạn chứa nhiều tài liệu, thì

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
94 hoặc các trình bao bọc của nó sẽ đưa ra một ngoại lệ

Trước đây, bạn đã sắp xếp một đối tượng Python thành YAML bằng cách lạm dụng mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
73 tích hợp, nhưng kết quả không phải là một dạng YAML chính tắc. Bây giờ, bạn sẽ tận dụng thư viện PyYAML bên thứ ba đã cài đặt để sửa lỗi này. Có một hàm
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
96 tương ứng, lấy một đối tượng Python và biến nó thành một chuỗi. Bạn có thể cung cấp cho nó đầu ra của
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
90 để đảo ngược quá trình phân tích cú pháp

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
4

Kết quả là một đối tượng chuỗi có thông báo email của bạn được tuần tự hóa lại thành YAML. Tuy nhiên, nó không hoàn toàn giống với YAML mà bạn đã bắt đầu với ban đầu. Như bạn có thể thấy,

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
98 đã sắp xếp các khóa từ điển cho bạn, trích dẫn các chuỗi nhiều dòng và sử dụng cách thụt đầu dòng hơi khác. Bạn có thể thay đổi một số điều này và áp dụng nhiều điều chỉnh hơn cho định dạng thông qua một số đối số từ khóa mà bạn sẽ khám phá trong một trong các phần sắp tới

Đang tải tài liệu YAML bằng Python

Việc tải YAML có nghĩa là đọc một đoạn văn bản và phân tích cú pháp nó theo ngữ pháp của định dạng dữ liệu. PyYAML có thể khiến điều này trở nên khó hiểu do có rất nhiều hàm và lớp để lựa chọn. Ngoài ra, tài liệu của thư viện không giải thích rõ ràng sự khác biệt và các trường hợp sử dụng hợp lệ của chúng. To save you from debugging the underlying code, you’ll find the most important facts about loading documents with PyYAML in this section

Chọn lớp Trình tải

If you want the best possible parsing performance, then you’ll need to manually import the suitable loader class and pass it to the generic

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
92 function, as shown before. Nhưng bạn nên chọn cái nào?

Để tìm hiểu, hãy xem tổng quan cấp cao này về các bộ tải theo ý của bạn. Các mô tả ngắn gọn sẽ cung cấp cho bạn một ý tưởng chung về các lựa chọn có sẵn

Loader ClassFunctionDescription

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
00-Không giải quyết hoặc hỗ trợ bất kỳ thẻ nào và chỉ xây dựng các đối tượng Python cơ bản [
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
01,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
02,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
03]
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
04-Được lưu giữ để tương thích ngược nhưng nếu không thì giống như
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
07Hỗ trợ tất cả các thẻ tiêu chuẩn, thư viện và thẻ tùy chỉnh và có thể xây dựng một Python tùy ý

Ba trình tải mà bạn có nhiều khả năng sử dụng nhất có các hàm tốc ký tương ứng mà bạn có thể gọi hàm này thay vì chuyển một lớp trình tải sang hàm chung chung

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
92. Hãy nhớ rằng, tất cả những thứ này đều được viết bằng Python, vì vậy để cải thiện hiệu suất, bạn sẽ cần nhập một lớp trình tải phù hợp có tiền tố là chữ C, chẳng hạn như
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
14 và vẫn gọi
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
92

Để biết phân tích chi tiết hơn về các tính năng được hỗ trợ bởi các lớp trình tải riêng lẻ, hãy xem bảng bên dưới

Loader ClassAnchors, AliasesYAML TagsPyYAML TagsCác loại phụ trợCác loại tùy chỉnhThực thi mã

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05 [
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
04]✔️✔️✔️✔️✔️✔️
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
11✔️✔️✔️✔️lỗilỗi
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
08✔️✔️lỗi✔️lỗilỗi
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
00✔️ignoreignoreignoreignore

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05 hỗ trợ tất cả các tính năng có sẵn và cho phép thực thi mã tùy ý.
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
11 cũng tương tự ngoại trừ việc thực thi mã và khả năng giải tuần tự hóa các lớp Python tùy chỉnh, gây ra lỗi phân tích cú pháp. Ngoài ra,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
08 còn xảy ra lỗi trên các thẻ dành riêng cho Python do PyYAML cung cấp, chẳng hạn như
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
24. Mặt khác,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
00 vẫn không biết gì về hầu hết các tính năng bằng cách bỏ qua chúng

Loại bỏ các quảng cáo

Compare Loaders’ Features

Below, you’ll get a quick demonstration of the features mentioned above. First, import the

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
89 module and check out an anchors and aliases example

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
5

You define an anchor,

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
27, near the shipping address and then reuse the same address for the invoice with the help of an alias,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
28. As a result, you only had to specify the address once. This feature works with all loader types

The next example shows one of the standard YAML tags in action

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
6

Numeric literals such as

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
23 are treated as floats by default, but you can request a type conversion to string with the
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
52 tag. Almost all loaders respect standard YAML tags. The only exception is the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
00 class, which represents scalars with strings whether you tag them or not

To leverage PyYAML tags, which are provided by the library, use either

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
11 or
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05 because they’re the only loaders that can handle Python-specific tags

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
7

The

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
24 tag in the example above converts an inline list into a Python tuple. Head over to PyYAML documentation for a complete list of supported tags, but be sure to cross-check with the source code on GitHub, as the documentation might not be up to date

Most loaders are smart about deserializing scalars into auxiliary types, which are more specific than a basic string, list, or dictionary

>>>

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
8

Here, you have a mix of types, including a

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
35, a
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
36, a
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
77 instance, an
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
38, and a
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
39. Again,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
00 is the only loader class that treats all scalars as strings at all times

Suppose you’d like to deserialize a custom class from YAML, make a function call in your Python code, or even execute a shell command while parsing YAML. In that case, your only option is the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05, which accepts a few special library tags. The other loaders either raise an exception or ignore those tags. You’ll learn more about the PyYAML tags now

Explore Loaders’ Insecure Features

PyYAML lets you serialize and deserialize any picklable Python object by tapping into its interface. Bear in mind that this allows for arbitrary code execution, as you’ll soon find out. However, if you don’t care about compromising your application’s security, then this capability can be pretty convenient

The library provides a couple of YAML tags recognized by

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
05 to accomplish object creation

  • %YAML 1.2
    ---
    person:
      dateOfBirth: 1969-12-31
      firstName: John
      lastName: Doe
      married: true
      spouse:
        dateOfBirth: null  # This is a comment
        firstName: Jane
        lastName: Doe
    
    43
  • %YAML 1.2
    ---
    person:
      dateOfBirth: 1969-12-31
      firstName: John
      lastName: Doe
      married: true
      spouse:
        dateOfBirth: null  # This is a comment
        firstName: Jane
        lastName: Doe
    
    44
  • %YAML 1.2
    ---
    person:
      dateOfBirth: 1969-12-31
      firstName: John
      lastName: Doe
      married: true
      spouse:
        dateOfBirth: null  # This is a comment
        firstName: Jane
        lastName: Doe
    
    45

They all must be followed by a fully qualified name of the class to instantiate, which includes the package and module names. The first tag expects a mapping of key-value pairs, in either the flow or block style. Here’s an example

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
9

The other two tags are more complicated, as each one comes in two flavors. However, the two tags are almost identical because

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
44 delegates processing to
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
45. The only difference is that
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
44 calls the special method
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
49 on the specified class without calling
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
50, while
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
45 invokes the class itself, which is what you’ll want in most cases

One flavor of the syntax allows for setting the object’s initial state through a list of positional arguments, like so

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
0

Both styles achieve a similar effect by calling the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
50 method in the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
53 class with the two values passed as positional arguments. Alternatively, you can use a slightly more verbose syntax that allows you to mix positional and keyword arguments, among a few more advanced tricks glossed over for brevity

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
1

This would still call

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
50 on your class, but one of the arguments would be passed as a keyword argument. In any case, you could define the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
53 class manually or by taking advantage of data classes in Python

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
2

This concise syntax will make Python generate the class initializer as well as a few other methods that you’d have to code yourself

Note that you can use

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
45 against any callable object, including regular functions, and specify the arguments to pass. This lets you execute one of the built-in functions, a custom function, or even a module-level function, which PyYAML will happily import for you. That’s a huge security hole. Imagine using the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
57 or
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
58 module to run a shell command that retrieves your private SSH key if you’ve defined one

>>>

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
3

It’s not hard to make an HTTP request with the stolen data through the network when the object gets created. A bad actor could use this information to access sensitive resources using your identity

Sometimes, these tags bypass the normal object creation path, which is typical of object serialization mechanisms in general. Say you wanted to load a user object from YAML and make it an instance of the following class

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
4

You place the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
59 class in a separate source file named
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
60 to keep things organized. User objects have only one attribute—the name. By using just one attribute and implementing the initializer explicitly, you’ll be able to observe the way PyYAML calls the individual methods

When you decide to use the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
43 tag in YAML, then the library calls
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
49 without any arguments and never calls
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
50. Instead, it directly manipulates the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
64 attribute of your newly created object, which can have some undesired effects

>>>

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
5

While you’ve undoubtedly created a new

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
59 instance, it wasn’t initialized properly, because the
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
66 attribute was missing. However, it does have an unexpected
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
67, which is nowhere to be found in the class body

You can fix this by adding a

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
68 declaration to your class, which forbids adding or removing attributes dynamically once the object exists in memory

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
6

Now, your user objects won’t have the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
64 attribute at all. Because there’s no inherent
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
64, the library falls back to calling
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
71 for each key-value pair on the blank object. This ensures that only attributes listed in
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
68 will pass through

This is all great, but what if the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
59 class accepted a password argument? To mitigate data leaks, you most definitely don’t want to serialize passwords in plaintext. And how about serializing stateful attributes, such as file descriptors or database connections? Well, if restoring your object’s state requires some code to run, then you can customize the serialization process with the special
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
74 method in your class

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
7

You decode the persisted username using a primitive ROT-13 cipher, which rotates characters by thirteen places in the alphabet. For serious encryption, though, you’ll have to look beyond the standard library. Note that you could also use a hashing algorithm from the built-in

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
75 module if you wanted to store a password securely

Here’s one way of loading your encoded state from YAML

>>>

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
8

As long as you’ve defined the

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
74 method, it’ll always take precedence and give you control over setting an object’s state. That’s why you’re able to restore the original name,
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
77, from the encoded text above

Before moving on, it’s worth noting that PyYAML provides two more insecure tags

  • %YAML 1.2
    ---
    person:
      dateOfBirth: 1969-12-31
      firstName: John
      lastName: Doe
      married: true
      spouse:
        dateOfBirth: null  # This is a comment
        firstName: Jane
        lastName: Doe
    
    78
  • %YAML 1.2
    ---
    person:
      dateOfBirth: 1969-12-31
      firstName: John
      lastName: Doe
      married: true
      spouse:
        dateOfBirth: null  # This is a comment
        firstName: Jane
        lastName: Doe
    
    79

The first one lets you load a reference to a Python object, such as a class, a function, or a variable, in your code. The second tag allows for referencing a given Python module. In the next section, you’ll take a look at different data sources that PyYAML lets you load documents from

Loại bỏ các quảng cáo

Load a Document From a String, a File, or a Stream

Once you choose the loader class or use one of the shorthand functions, you’re not limited to parsing only strings. The

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
91 and other functions exposed by PyYAML accept a single argument, which is a universal stream of characters or bytes. The most common examples of such streams are strings and Python
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
55 objects

>>>

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
9

Theo YAML 1. 2, trình phân tích cú pháp phải hỗ trợ Unicode được mã hóa bằng UTF-8, UTF-16 hoặc UTF-32 để tương thích với JSON. Tuy nhiên, do thư viện PyYAML chỉ hỗ trợ YAML 1. 1, các tùy chọn duy nhất của bạn là UTF-8 và UTF-16

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
0

Nếu bạn thử tải YAML từ một văn bản được mã hóa bằng UTF-32 thì bạn sẽ gặp lỗi. Tuy nhiên, đó không phải là vấn đề trong thực tế vì UTF-32 không phải là mã hóa phổ biến. Trong mọi trường hợp, bạn luôn có thể tự mình thực hiện chuyển mã thích hợp bằng cách sử dụng các phương thức

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
82 và
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
83 của Python trước khi tải YAML. Ngoài ra, bạn có thể thử một trong các thư viện phân tích cú pháp YAML khác đã đề cập trước đó

Bạn cũng có thể đọc nội dung YAML trực tiếp từ một tệp. Hãy tiếp tục và tạo một tệp có nội dung YAML mẫu trong đó và tải nó vào Python bằng PyYAML

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
1

Bạn tạo một tệp cục bộ có tên

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
84 trong thư mục làm việc hiện tại của mình và viết mười bốn byte đại diện cho một tài liệu YAML mẫu. Tiếp theo bạn mở file đó ra đọc và dùng
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
91 để lấy từ điển tương ứng. Tệp có thể được mở ở chế độ văn bản hoặc nhị phân. Trên thực tế, bạn có thể chuyển bất kỳ luồng ký tự hoặc byte giống như tệp nào, chẳng hạn như lệnh io trong bộ nhớ. Bộ đệm văn bản StringIO hoặc io nhị phân. Luồng byteIO

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
2

Như bạn có thể thấy, các chức năng tải trong PyYAML khá linh hoạt. So sánh điều này với mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
73, cung cấp các chức năng khác nhau tùy thuộc vào loại đối số đầu vào của bạn. Tuy nhiên, PyYAML gói một bộ chức năng khác có thể giúp bạn đọc nhiều tài liệu từ một luồng. Bạn sẽ tìm hiểu về các chức năng đó ngay bây giờ

Tải nhiều tài liệu

Tất cả bốn chức năng tải trong PyYAML đều có các đối tác có thể lặp lại của chúng, có thể đọc nhiều tài liệu YAML từ một luồng. Họ vẫn mong đợi chính xác một đối số, nhưng thay vì ngay lập tức phân tích nó thành một đối tượng Python, họ gói nó bằng một trình lặp trình tạo mà bạn có thể lặp lại

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
3

Các tài liệu riêng lẻ phải bắt đầu bằng dấu ba gạch ngang [_______171] và có thể tùy ý kết thúc bằng dấu ba chấm [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
72]

Trong phần này, bạn đã tìm hiểu về các chức năng cấp cao có sẵn trong PyYAML để tải tài liệu bằng. Thật không may, họ cố gắng háo hức đọc toàn bộ luồng trong một lần, điều này không phải lúc nào cũng khả thi. Đọc các tệp lớn theo cách như vậy có thể mất quá nhiều thời gian hoặc thậm chí không thành công do bộ nhớ hạn chế. Nếu bạn muốn xử lý YAML theo kiểu phát trực tuyến tương tự như giao diện SAX trong XML, thì bạn phải sử dụng API cấp thấp do PyYAML cung cấp

Kết xuất các đối tượng Python vào tài liệu YAML

Nếu bạn đã từng làm việc với JSON trong Python trước đây, thì việc tuần tự hóa hoặc “kết xuất” các đối tượng Python sang YAML sẽ trông quen thuộc hơn là tải chúng. Thư viện PyYAML có giao diện hơi giống với mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
73 tích hợp. Nó cũng cung cấp ít lớp trình kết xuất và chức năng trình bao bọc hơn so với trình tải để lựa chọn, vì vậy bạn không cần phải sắp xếp nhiều tùy chọn đó

Chọn lớp Dumper

Hàm tuần tự hóa YAML toàn diện trong PyYAML là

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90, lấy một lớp trình kết xuất tùy chọn làm đối số. Nếu bạn không chỉ định một trong khi gọi hàm, thì nó sẽ quay trở lại sử dụng
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
91 giàu tính năng nhất. Các lựa chọn khác như sau

Lớp DumperChức năngMô tả

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
92
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
93Không hỗ trợ bất kỳ thẻ nào và chỉ hữu ích cho phân lớp
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
94
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
98Chỉ tạo các thẻ YAML tiêu chuẩn như
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
52 và không thể đại diện cho các thể hiện của lớp, làm cho nó tương thích hơn với các trình phân tích cú pháp YAML khác
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
97
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
98Hỗ trợ tất cả các thẻ tiêu chuẩn, thư viện và thẻ tùy chỉnh và có thể tuần tự hóa một đối tượng Python tùy ý

Trong thực tế, sự lựa chọn thực sự mà bạn có sẽ nằm trong khoảng từ

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
97 đến
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
94 vì
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
92 chỉ nhằm mục đích làm lớp cơ sở cho các lớp con mở rộng. Nói chung, bạn sẽ muốn sử dụng
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
91 mặc định trong hầu hết các trường hợp trừ khi bạn cần tạo YAML di động mà không cần các yêu cầu cụ thể của Python

Một lần nữa, hãy nhớ nhập lớp trình kết xuất tương ứng có tiền tố là chữ C để có hiệu suất tuần tự hóa tốt nhất và lưu ý rằng có thể có một số khác biệt nhỏ giữa triển khai Python và C

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
4

Ví dụ: trình kết xuất Python thuần túy nối thêm các dấu chấm tùy chọn ở cuối tài liệu YAML, trong khi một lớp trình bao bọc tương tự cho thư viện LibYAML thì không. Tuy nhiên, đây là những khác biệt về mặt thẩm mỹ không có tác động thực sự đến dữ liệu được xê-ri hóa hoặc giải tuần tự hóa

Loại bỏ các quảng cáo

Kết xuất thành Chuỗi, Tệp hoặc Luồng

Tuần tự hóa JSON trong Python yêu cầu bạn chọn giữa việc gọi

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
03 hoặc
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
74 tùy thuộc vào nơi bạn muốn nội dung được kết xuất. Mặt khác, PyYAML cung cấp chức năng kết xuất hai trong một, hoạt động khác nhau tùy thuộc vào cách bạn gọi nó

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
5

When called with a single argument, the function returns a string representing the serialized object. Tuy nhiên, bạn có thể tùy ý chuyển đối số thứ hai để chỉ định luồng mục tiêu sẽ ghi vào. Nó có thể là một tệp hoặc bất kỳ đối tượng giống tệp nào. Khi bạn chuyển đối số tùy chọn này, hàm trả về

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
36 và bạn cần trích xuất dữ liệu từ luồng nếu cần

Nếu bạn muốn kết xuất YAML của mình vào một tệp, hãy nhớ mở tệp ở chế độ ghi. Ngoài ra, bạn phải chỉ định mã hóa ký tự thông qua đối số từ khóa tùy chọn cho hàm

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90 khi tệp được mở ở chế độ nhị phân

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
6

Khi bạn mở một tệp ở chế độ văn bản, bạn nên đặt mã hóa ký tự một cách rõ ràng. Nếu không, Python sẽ sử dụng mã hóa mặc định của nền tảng của bạn, mã hóa này có thể ít di động hơn. Mã hóa ký tự không có ý nghĩa gì trong chế độ nhị phân, xử lý các byte đã được mã hóa. Tuy nhiên, bạn nên đặt mã hóa thông qua hàm

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90, hàm này chấp nhận nhiều tham số tùy chọn khác mà bạn sẽ sớm tìm hiểu

Kết xuất nhiều tài liệu

Hai chức năng kết xuất YAML trong PyYAML,

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
98 và
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
98, không có cách nào để biết liệu bạn định sắp xếp theo thứ tự nhiều tài liệu riêng biệt hay một tài liệu duy nhất bao gồm một chuỗi phần tử

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
7

Họ luôn giả định cái sau, kết xuất một tài liệu YAML duy nhất với một danh sách các phần tử. Để kết xuất nhiều tài liệu, hãy sử dụng

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
10 hoặc
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
11

>>>

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
8

Bây giờ bạn nhận được một chuỗi chứa nhiều hơn một tài liệu YAML được phân tách bằng ba dấu gạch ngang [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
71]

Lưu ý rằng

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
10 là hàm duy nhất được sử dụng ngầm vì tất cả các hàm khác, bao gồm cả
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
98 và
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
98, ủy quyền xử lý cho nó. Vì vậy, bất kể bạn gọi hàm nào, tất cả chúng sẽ có cùng một danh sách các tham số hình thức

Tinh chỉnh định dạng với các tham số tùy chọn

Các hàm kết xuất trong PyYAML chấp nhận một vài đối số vị trí và một số đối số từ khóa tùy chọn, cho phép bạn kiểm soát định dạng của đầu ra. Tham số bắt buộc duy nhất là đối tượng Python hoặc một chuỗi các đối tượng để tuần tự hóa, được chuyển làm đối số đầu tiên trong tất cả các hàm kết xuất. Bạn sẽ xem xét kỹ hơn các tham số có sẵn trong phần này

Ba hàm bao ủy quyền cho

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
16 có các chữ ký hàm sau, cho biết các đối số vị trí của chúng

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
9

Hàm đầu tiên mong đợi từ một đến ba đối số vị trí vì hai trong số chúng có giá trị tùy chọn. Mặt khác, hàm thứ hai và thứ ba được liệt kê ở trên chỉ mong đợi hai đối số vị trí bởi vì cả hai đều sử dụng một

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
94 được xác định trước. Để tìm các đối số từ khóa có sẵn, bạn phải xem chữ ký của hàm
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
16

Bạn có thể sử dụng các đối số từ khóa giống nhau trên cả bốn hàm kết xuất. Tất cả chúng đều là tùy chọn vì chúng có giá trị mặc định bằng

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
36 hoặc
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
20, ngoại trừ đối số
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
21 có giá trị mặc định là
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
09. Tổng cộng, có sáu cờ Boolean mà bạn có thể bật và tắt để thay đổi giao diện của kết quả YAML

Cờ BooleanÝ nghĩa

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
23Không thoát khỏi Unicode và không trích dẫn kép.
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
24Đầu ra YAML ở dạng chính tắc.
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
25Prefer flow style over block style.
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
26Kết thúc mỗi tài liệu bằng dấu ba chấm [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
72].
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
28Bắt đầu mỗi tài liệu bằng dấu gạch ngang ba lần [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
71].
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
21Sắp xếp đầu ra của từ điển theo khóa

Ngoài ra còn có một số tham số của các loại dữ liệu khác giúp bạn tự do hơn

Tham sốTypeMeaning

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
31
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
38Mức thụt lề khối, phải lớn hơn 1 và nhỏ hơn 10
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
33
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
38Chiều rộng dòng, phải lớn hơn hai lần thụt lề
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
35
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
01Kiểu trích dẫn vô hướng, phải là một trong những kiểu sau.
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
36,
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
38 hoặc
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
39
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
40
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
01Mã hóa ký tự, tạo ra
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
55 thay vì
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
01 khi đặt
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
44
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
01Ký tự xuống dòng, phải là một trong các ký tự sau.
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
46,
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
47 hoặc
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
48
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
49
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
03Các chỉ thị thẻ bổ sung bao gồm các tay cầm thẻ
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
51
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
52Phiên bản YAML chính và phụ, chẳng hạn như
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
53 cho phiên bản 1. 2

Hầu hết trong số họ là tự giải thích. Tuy nhiên, đối số

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
49 phải là một từ điển ánh xạ các thẻ tùy chỉnh xử lý thành các tiền tố URI hợp lệ được trình phân tích cú pháp YAML nhận dạng

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
80

Việc chỉ định ánh xạ như vậy sẽ thêm chỉ thị thẻ có liên quan vào tài liệu được kết xuất của bạn. Tay cầm thẻ luôn bắt đầu và kết thúc bằng dấu chấm than. Chúng là ký hiệu viết tắt cho tên thẻ đầy đủ. Ví dụ: đây là tất cả các cách tương đương để sử dụng cùng một thẻ trong tài liệu YAML

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
81

Bằng cách sử dụng lệnh

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
55 phía trên tài liệu YAML, bạn khai báo một thẻ xử lý tùy chỉnh có tên là
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
56, được mở rộng thành tiền tố sau. Dấu chấm than kép [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
51] là lối tắt tích hợp cho không gian tên mặc định tương ứng với tiền tố
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
58

Bạn có thể thử nghiệm với các đối số từ khóa có sẵn bằng cách thay đổi giá trị của chúng và chạy lại mã của bạn để xem kết quả. Tuy nhiên, điều này nghe có vẻ như là một nhiệm vụ tẻ nhạt. Các tài liệu hỗ trợ cho hướng dẫn này đi kèm với một ứng dụng tương tác cho phép bạn kiểm tra các cách kết hợp khác nhau của đối số và giá trị của chúng trong trình duyệt web

Đó là một trang web động sử dụng JavaScript để giao tiếp qua mạng với một máy chủ HTTP tối thiểu được viết bằng FastAPI. Máy chủ mong đợi một đối tượng JSON có tất cả trừ đối số từ khóa

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
49 và gọi
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90 đối với đối tượng thử nghiệm sau

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
82

Đối tượng mẫu ở trên là một từ điển bao gồm các trường số nguyên và chuỗi, chứa các ký tự Unicode. Để chạy máy chủ, trước tiên bạn phải cài đặt thư viện FastAPI và máy chủ web ASGI chẳng hạn như uvicorn vào môi trường ảo của bạn, nơi bạn đã cài đặt PyYAML trước đó

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
83

Để chạy máy chủ, bạn phải cung cấp tên mô-đun theo sau là dấu hai chấm và tên có thể gọi tương thích với ASGI trong mô-đun đó. Các chi tiết về cách triển khai một máy chủ và máy khách như vậy nằm ngoài phạm vi của hướng dẫn này, nhưng vui lòng tải xuống các tài liệu mẫu để tự nghiên cứu

Nhận mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để làm việc với YAML trong Python

Tiếp theo, bạn sẽ tìm hiểu thêm về cách kết xuất các lớp tùy chỉnh với PyYAML

Loại bỏ các quảng cáo

Kết xuất các loại dữ liệu tùy chỉnh

Như bạn đã biết, tại thời điểm này, bạn có thể sử dụng một trong các thẻ dành riêng cho Python do PyYAML cung cấp để tuần tự hóa và giải tuần tự hóa các đối tượng thuộc loại dữ liệu tùy chỉnh của mình, chẳng hạn như các lớp. Bạn cũng biết rằng các thẻ đó chỉ được nhận dạng bởi trình tải và trình kết xuất không an toàn, cho phép thực thi mã nguy hiểm tiềm tàng một cách rõ ràng. Thư viện sẽ từ chối tuần tự hóa một loại dành riêng cho Python như số phức trừ khi bạn chọn lớp trình kết xuất không an toàn

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
84

Trong trường hợp đầu tiên, trình kết xuất an toàn không biết cách biểu thị số phức của bạn trong YAML. Mặt khác, việc gọi

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90 ngầm sử dụng lớp
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
62 không an toàn ở hậu trường, điều này lợi dụng thẻ
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
63. Đó là một câu chuyện tương tự khi bạn cố gắng kết xuất một lớp tùy chỉnh

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
85

Lựa chọn duy nhất của bạn là

%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
90 không an toàn. Tuy nhiên, có thể đánh dấu các lớp của bạn là an toàn để phân tích cú pháp để ngay cả trình tải an toàn cũng có thể xử lý chúng sau này. Để làm điều đó, bạn phải thực hiện một vài thay đổi đối với lớp học của mình

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
86

Đầu tiên, hãy để lớp kế thừa từ

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
65. Sau đó chỉ định hai thuộc tính lớp. One attribute will represent a custom YAML tag tied to your class, while the second one will be the loader class to use. Bây giờ, khi bạn kết xuất một đối tượng
%YAML 1.2
---
person:
  dateOfBirth: 1969-12-31
  firstName: John
  lastName: Doe
  married: true
  spouse:
    dateOfBirth: null  # This is a comment
    firstName: Jane
    lastName: Doe
53 vào YAML, bạn sẽ có thể tải lại đối tượng đó bằng
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
90

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
87

Toán tử Walrus [

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
68] cho phép bạn xác định một biến và sử dụng nó làm đối số cho hàm
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
69 trong một bước. Đánh dấu các lớp là an toàn là một thỏa hiệp tốt, cho phép bạn tạo ngoại lệ cho một số lớp của mình bằng cách loại bỏ bảo mật và cho phép chúng vào. Đương nhiên, bạn phải hoàn toàn chắc chắn rằng không có gì đáng ngờ về chúng trước khi thử tải YAML được liên kết

Phân tích tài liệu YAML ở mức thấp

Các lớp và một số hàm trình bao bọc mà bạn đã sử dụng cho đến nay tạo thành một giao diện PyYAML cấp cao, ẩn các chi tiết triển khai khi làm việc với các tài liệu YAML. This covers most of the use cases and allows you to focus on the data rather than its presentation. Tuy nhiên, đôi khi bạn có thể muốn kiểm soát nhiều hơn quá trình phân tích cú pháp và tuần tự hóa

Trong những trường hợp hiếm hoi đó, thư viện sẽ hiển thị hoạt động bên trong của nó cho bạn thông qua một số chức năng cấp thấp. Có bốn cách để đọc luồng YAML

Chức năng đọc Giá trị trả vềLazy?

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
70Tokens✔️
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
71Events✔️
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
72Node
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
73Nodes✔️

Tất cả các chức năng này chấp nhận một luồng và một lớp trình tải tùy chọn, mặc định là

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
74. Ngoài ra, hầu hết chúng trả về một đối tượng trình tạo, cho phép bạn xử lý YAML theo kiểu phát trực tuyến, điều không thể thực hiện được cho đến thời điểm này. Bạn sẽ tìm hiểu về sự khác biệt giữa mã thông báo, sự kiện và nút sau đó

Ngoài ra còn có một số hàm đối ứng để ghi YAML vào luồng

Writing FunctionInputExample

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
75Events
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
76
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
77Node
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
78
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
79Nodes
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
80

Lưu ý rằng bất kể chức năng nào bạn chọn, có thể bạn sẽ có nhiều việc phải làm hơn trước. Ví dụ: xử lý các thẻ YAML hoặc diễn giải các giá trị chuỗi thành loại dữ liệu gốc chính xác sẽ có trong tòa án của bạn ngay bây giờ. Tuy nhiên, một số bước này có thể không cần thiết, tùy thuộc vào trường hợp sử dụng của bạn

Trong phần này, bạn sẽ triển khai ba ví dụ thực hành về các hàm cấp thấp này trong PyYAML. Hãy nhớ rằng bạn có thể tải xuống mã nguồn của họ bằng cách nhấp vào liên kết bên dưới

Nhận mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để làm việc với YAML trong Python

Loại bỏ các quảng cáo

Mã hóa tài liệu YAML

Bạn sẽ có quyền kiểm soát chi tiết nhất bằng cách quét tài liệu YAML để lấy luồng mã thông báo. Mỗi mã thông báo có một ý nghĩa duy nhất và cho bạn biết nơi nó bắt đầu và nơi nó kết thúc, bao gồm số dòng và cột chính xác, cũng như phần bù từ phần đầu của tài liệu

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
88

Thuộc tính

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
81 và
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
82 của mã thông báo chứa tất cả thông tin liên quan. Điều đó thật hoàn hảo nếu bạn muốn triển khai plugin đánh dấu cú pháp YAML cho trình chỉnh sửa mã yêu thích của mình chẳng hạn. Trên thực tế, tại sao bạn không tiếp tục và xây dựng một công cụ dòng lệnh cơ bản để in nội dung YAML có màu?

Trước tiên, bạn cần thu hẹp các loại mã thông báo, vì bạn sẽ chỉ quan tâm đến việc tô màu các giá trị vô hướng, khóa ánh xạ và thẻ YAML. Tạo một tệp mới có tên

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
83 và đặt hàm sau vào đó

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
89

Đó là một trình bao bọc mỏng xung quanh hàm

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
70 của PyYAML, tạo ra các bộ dữ liệu bao gồm chỉ mục bắt đầu, chỉ mục kết thúc và một phiên bản mã thông báo. Đây là một sự cố chi tiết hơn

  • Dòng 6 định nghĩa một biến để giữ phiên bản mã thông báo cuối cùng. Chỉ có scalar và tag token mới chứa giá trị nên bạn phải nhớ ngữ cảnh của chúng ở đâu đó để sau này chọn màu cho phù hợp. Giá trị ban đầu chiếm khi tài liệu chỉ chứa một đại lượng vô hướng mà không có bất kỳ ngữ cảnh nào
  • Dòng 7 lặp lại các mã thông báo được quét
  • Dòng 8 và 9 trích xuất vị trí của mã thông báo trong văn bản từ các điểm đánh dấu chỉ mục có sẵn trên tất cả các mã thông báo. Vị trí của mã thông báo được phân định bằng
    grandparent:
      parent:
        child:
          name: Bobby
        sibling:
          name: Molly
    
    85 và
    grandparent:
      parent:
        child:
          name: Bobby
        sibling:
          name: Molly
    
    86
  • Dòng 10 đến 13 kiểm tra loại mã thông báo hiện tại và đưa ra các chỉ số cũng như phiên bản mã thông báo. Nếu mã thông báo là một thẻ, thì nó sẽ được mang lại. Nếu mã thông báo là vô hướng, thì
    grandparent:
      parent:
        child:
          name: Bobby
        sibling:
          name: Molly
    
    87 được tạo ra vì vô hướng có thể xuất hiện trong các ngữ cảnh khác nhau và bạn cần biết ngữ cảnh hiện tại là gì để chọn màu phù hợp
  • Dòng 14 và 15 cập nhật ngữ cảnh nếu mã thông báo hiện tại là khóa ánh xạ hoặc giá trị. Các loại mã thông báo khác bị bỏ qua vì chúng không có hình ảnh đại diện có ý nghĩa

Khi bạn nhập chức năng của mình vào phiên trình thông dịch Python tương tác, thì bạn sẽ có thể bắt đầu lặp qua tập hợp con mã thông báo với các chỉ số liên quan của chúng

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
00

Gọn gàng. Bạn có thể tận dụng các bộ dữ liệu này để chú thích mã thông báo trong văn bản gốc bằng cách sử dụng thư viện của bên thứ ba hoặc chuỗi thoát ANSI miễn là thiết bị đầu cuối của bạn hỗ trợ chúng. Dưới đây là một vài màu mẫu với trình tự thoát của chúng

MàuTrọng lượng phông chữTrình tự thoátXanh đậm

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
88CyanThông thường
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
89ĐỏThông thường
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
90

Ví dụ: các khóa có thể chuyển sang màu xanh lam, giá trị có thể chuyển sang màu lục lam và thẻ YAML có thể chuyển sang màu đỏ. Hãy nhớ rằng bạn không thể sửa đổi một chuỗi các phần tử trong khi lặp lại chúng, vì điều đó sẽ làm thay đổi chỉ số của chúng. Tuy nhiên, những gì bạn có thể làm là bắt đầu lặp lại từ đầu bên kia. Bằng cách đó, việc chèn các chuỗi thoát sẽ không ảnh hưởng đến phần còn lại của văn bản

Quay lại trình chỉnh sửa mã của bạn ngay bây giờ và thêm một chức năng khác vào tệp nguồn Python

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
01

Chức năng mới này lặp lại một văn bản được mã hóa ngược lại và chèn các chuỗi mã thoát vào nơi được chỉ định bởi

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
85 và
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
86. Lưu ý rằng đó không phải là cách hiệu quả nhất để thực hiện việc này, vì về cơ bản, bạn sẽ tạo ra nhiều bản sao văn bản do cắt và nối

Phần cuối cùng của câu đố là lấy YAML từ đầu vào tiêu chuẩn và hiển thị nó trên luồng đầu ra tiêu chuẩn

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
02

Bạn nhập mô-đun

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
93 từ thư viện chuẩn của Python và chuyển tham chiếu
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
94 đến hàm
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
95 mà bạn vừa tạo. Bây giờ, bạn có thể chạy tập lệnh của mình trong thiết bị đầu cuối và tận hưởng mã thông báo YAML được mã hóa màu

Lưu ý rằng lệnh

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
96 không khả dụng trên Windows. Nếu đó là hệ điều hành của bạn, thì hãy sử dụng đối tác
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
97 của nó và đảm bảo chạy lệnh thông qua ứng dụng Terminal thay vì Dấu nhắc Lệnh [
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
98] hoặc Windows PowerShell để hỗ trợ mã thoát ANSI được bật theo mặc định

Mở rộng phần có thể thu gọn bên dưới để có mã nguồn hoàn chỉnh cho tập lệnh của bạn

Mã nguồn hoàn chỉnhHiển thị/Ẩn

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
03

Mã hóa là tuyệt vời để triển khai một cú pháp tô sáng, phải có khả năng tham chiếu các ký hiệu trong tệp YAML nguồn. Tuy nhiên, nó có thể hơi quá thấp đối với các ứng dụng khác không quan tâm đến bố cục chính xác của dữ liệu đầu vào của bạn. Tiếp theo, bạn sẽ tìm hiểu về một cách khác để xử lý YAML, cũng liên quan đến việc phát trực tuyến

Phân tích một luồng sự kiện

Một giao diện cấp thấp khác do PyYAML cung cấp là API phát trực tuyến theo sự kiện, hoạt động tương tự như SAX trong XML. Nó dịch YAML thành một chuỗi các sự kiện được kích hoạt bởi các phần tử riêng lẻ. Các sự kiện được đánh giá một cách lười biếng mà không tải toàn bộ tài liệu vào bộ nhớ. Bạn có thể coi nó như nhìn lén qua một cửa sổ đang chuyển động

Điều này có thể giúp bỏ qua giới hạn bộ nhớ mà bạn có thể gặp phải khi cố đọc một tệp lớn. Nó cũng có thể tăng tốc đáng kể việc tìm kiếm một mẩu thông tin rất cụ thể trong đại dương nhiễu. Ngoài ra, tính năng phát trực tuyến giúp bạn có thể từng bước xây dựng một biểu diễn thay thế cho dữ liệu của mình. Trong phần này, bạn sẽ tạo một trình tạo HTML để trực quan hóa YAML theo cách thô sơ

Khi bạn phân tích tài liệu bằng PyYAML, thư viện sẽ tạo ra một chuỗi sự kiện

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
04

Như bạn có thể thấy, có nhiều loại sự kiện tương ứng với các thành phần khác nhau trong tài liệu YAML. Một số sự kiện trong số đó hiển thị các thuộc tính bổ sung mà bạn có thể kiểm tra để tìm hiểu thêm về phần tử hiện tại

Bạn có thể tưởng tượng làm thế nào những sự kiện này có thể tự nhiên chuyển thành các thẻ mở và đóng trong ngôn ngữ đánh dấu phân cấp như HTML. Ví dụ: bạn có thể trình bày cấu trúc ở trên bằng đoạn mã đánh dấu sau

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
05

Một mục danh sách duy nhất được bao bọc giữa các thẻ

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
99 và
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
00, trong khi ánh xạ khóa-giá trị tận dụng danh sách mô tả [
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
01], chứa các thuật ngữ xen kẽ [
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
02] và định nghĩa [
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
03]. Đây là phần phức tạp vì nó yêu cầu đếm các sự kiện YAML tiếp theo ở cấp độ lồng nhau nhất định để xác định xem một sự kiện có nên trở thành thuật ngữ hay định nghĩa trong HTML hay không

Cuối cùng, bạn muốn thiết kế một lớp

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
04 để giúp bạn phân tích cú pháp nhiều tài liệu YAML từ một luồng theo cách lười biếng. Giả sử bạn đã định nghĩa một lớp như vậy, bạn có thể tạo hàm trợ giúp sau trong tệp có tên
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
05

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
06

Mã này lặp lại một chuỗi các sự kiện trình phân tích cú pháp và chuyển giao chúng cho lớp của bạn, lớp này dịch YAML sang HTML bằng cách xây dựng dần dần biểu diễn của nó. Khi chức năng phát hiện phần cuối của tài liệu YAML trong luồng, nó sẽ tạo ra một đoạn HTML và tạo trình tạo trống mới để bắt đầu lại. Điều đó tránh bị chặn trong quá trình xử lý luồng tài liệu YAML có khả năng dài vô tận, có thể đến qua dây

>>>

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
07

Ví dụ trên minh họa một luồng bao gồm ba tài liệu YAML, mà chức năng của trình trợ giúp biến thành các đoạn HTML riêng biệt. Bây giờ bạn đã hiểu hành vi dự kiến, đã đến lúc triển khai lớp

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
04

Phương thức khởi tạo trong lớp trình tạo của bạn sẽ xác định hai trường riêng tư để theo dõi ngữ cảnh hiện tại và nội dung HTML được tạo cho đến nay

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
08

Bối cảnh là một ngăn xếp được triển khai dưới dạng danh sách Python, lưu trữ số lượng cặp khóa-giá trị ở cấp độ đã cho được xử lý cho đến nay. Ngăn xếp cũng có thể chứa các dấu danh sách biểu thị trạng thái giữa

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
07 và
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
08. Trường còn lại là danh sách các thẻ HTML và nội dung của chúng, được nối với nhau bởi một thuộc tính lớp công khai

Có một số sự kiện YAML mà bạn muốn xử lý

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
09

Bạn bắt đầu xử lý một sự kiện bằng cách kiểm tra xem có bất kỳ thẻ mở nào trên ngăn xếp đang chờ xử lý một số hành động không. Bạn ủy thác việc kiểm tra này cho một phương thức trợ giúp khác,

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
09, mà bạn sẽ thêm vào sau. Then, you append the HTML tag corresponding to the current event and again update the context

Dưới đây là tóm tắt nhanh từng dòng của đoạn mã trên

  • Dòng 5 đến 11 nhập các loại sự kiện cần thiết từ PyYAML
  • Dòng 13 và 14 quy định các loại sự kiện tương ứng với thẻ mở và thẻ đóng HTML
  • Dòng 24 đến 37 nối thêm thẻ HTML tương ứng và cập nhật ngăn xếp nếu cần
  • Các dòng 21, 22, 39 và 40 mở hoặc đóng các thẻ đang chờ xử lý trên ngăn xếp và tùy chọn cập nhật số lượng cặp khóa-giá trị được xử lý

Phần còn thiếu là phương thức trợ giúp chịu trách nhiệm mở và đóng các thẻ phù hợp khi cần thiết

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
20

Nếu đã có thứ gì đó trên ngăn xếp, thì bạn kiểm tra mục cuối cùng được đẩy lên đó. Nếu đó là một danh sách, thì bạn mở hoặc đóng một mục danh sách. Mặt khác, tùy thuộc vào tính chẵn lẻ của số lượng ánh xạ khóa-giá trị, đã đến lúc mở hoặc đóng một thuật ngữ hoặc định nghĩa từ danh sách mô tả

You can optionally turn your Python module into an executable script by adding the

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
10 idiom at the bottom

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
21

Nó sẽ cho phép bạn xem trước biểu diễn trực quan của YAML trong thiết bị đầu cuối của mình khi bạn chuyển đầu ra HTML sang trình duyệt web dựa trên văn bản như Lynx hoặc trình chuyển đổi html2text

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
22

Lệnh

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
11 sẽ hoạt động trên tất cả các hệ điều hành chính. Nó in một đoạn văn bản trong thiết bị đầu cuối, bạn có thể nối đoạn văn bản này với một đường dẫn lệnh khác bằng cách sử dụng ký tự thanh dọc [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
68]. Trong trường hợp này, bạn xử lý một tài liệu YAML ngắn bằng tập lệnh
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
05 của mình, sau đó chuyển đổi HTML kết quả thành dạng văn bản đơn giản hóa mà bạn có thể xem trước trong thiết bị đầu cuối mà không cần khởi động trình duyệt web chính thức

Nhấp vào phần có thể thu gọn bên dưới để hiển thị mã nguồn hoàn chỉnh

Mã nguồn hoàn chỉnhHiển thị/Ẩn

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
23

Bạn đã làm rất tốt. Bây giờ bạn có thể hình dung YAML trong trình duyệt web của mình. Tuy nhiên, bản trình bày là tĩnh. Sẽ không hay nếu thêm một chút tương tác vào nó phải không?

Xây dựng một cây nút

Đôi khi, bạn cần lưu giữ toàn bộ tài liệu trong bộ nhớ để nhìn về phía trước và đưa ra quyết định sáng suốt dựa trên những gì xảy ra tiếp theo. PyYAML có thể xây dựng một biểu diễn đối tượng của hệ thống phân cấp phần tử YAML giống với DOM trong XML. Bằng cách gọi

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
72, bạn sẽ nhận được nút gốc của cây phần tử

>>>

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
24

Gốc có thể duyệt qua cú pháp dấu ngoặc vuông. Bạn có thể tiếp cận bất kỳ phần tử hậu duệ nào trong cây bằng cách sử dụng thuộc tính và các chỉ số dưới của nút

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
15

>>>

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
25

Vì chỉ có ba loại nút [

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
16,
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
17 và
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
18], bạn có thể tự động hóa quá trình truyền tải của chúng bằng hàm đệ quy

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
26

Đặt chức năng này trong tập lệnh Python có tên

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
19, vì bạn sẽ phát triển mã. Hàm nhận một nút duy nhất và tùy thuộc vào loại của nó, trả về giá trị của nó hoặc nhập một cây con có liên quan. Lưu ý rằng các khóa ánh xạ cũng phải được truy cập vì chúng có thể là các giá trị không vô hướng trong YAML

Sau đó, nhập chức năng của bạn trong phiên trình thông dịch Python tương tác và cung cấp cho nó một ổ đĩa thử nghiệm đối với phần tử gốc mà bạn đã tạo trước đó

>>>

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
27

Kết quả là bạn nhận được một danh sách Python, nhưng các giá trị vô hướng riêng lẻ chứa trong đó đều là các chuỗi. PyYAML phát hiện loại dữ liệu được liên kết với một giá trị vô hướng và lưu trữ nó trong thuộc tính

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
20 của nút, nhưng bạn phải tự mình thực hiện việc đánh máy. Các loại được mã hóa bằng các thẻ toàn cầu YAML, chẳng hạn như
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
21, vì vậy bạn có thể trích xuất bit cuối cùng sau dấu hai chấm thứ hai [_______70]

Sửa đổi chức năng của bạn bằng cách gói giá trị trả về của một đại lượng vô hướng bằng lệnh gọi đến một hàm

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
23 mới

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
28

Bạn có thể tận dụng các từ khóa

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
24 và
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
25 mới được giới thiệu trong Python 3. 10 với cú pháp đối sánh mẫu cấu trúc hoặc bạn có thể viết lại ví dụ này bằng cách sử dụng câu lệnh
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
26 đơn giản. Điểm mấu chốt là bây giờ bạn sẽ nhận được các giá trị của các loại Python gốc khi bạn tải lại mô-đun trong phiên thông dịch tương tác của mình

>>>

recursive: &cycle [*cycle]

exercises:
  - muscles: &push-up
      - pectoral
      - triceps
      - biceps
  - muscles: &squat
      - glutes
      - quadriceps
      - hamstrings
  - muscles: &plank
      - abs
      - core
      - shoulders

schedule:
  monday:
    - *push-up
    - *squat
  tuesday:
    - *plank
  wednesday:
    - *push-up
    - *plank
29

Bạn đã sẵn sàng tạo chuỗi HTML thay vì đối tượng Python. Thay thế các giá trị trả về trong

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
27 bằng các lệnh gọi đến nhiều hàm trợ giúp hơn

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
0

Cả hai hàm trợ giúp đều lấy một phiên bản nút và trả về một đoạn chuỗi HTML. Hàm

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
28 yêu cầu một
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
17 được lặp lại với một biểu thức trình tạo, trong khi đó,
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
30 lặp lại các khóa và giá trị của một
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
18. Đây là nơi biết trước toàn bộ cấu trúc cây giúp. Nếu giá trị ánh xạ là một
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
16, thì bạn thay thế nó bằng một phần tử
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
33. Các loại nút khác được bọc trong thẻ
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
34 có thể thu gọn

Vì bạn sẽ tạo đầu ra HTML, nên bạn có thể sắp xếp hợp lý chức năng đánh máy bằng cách chỉ trả về các chuỗi đơn giản. Đồng thời, bạn có thể trả về một phần tử HTML

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
35 cho dữ liệu được mã hóa Base64 và hiển thị phần tử đó thay vì hiển thị các byte thô. Ngoài ra, các đại lượng vô hướng thông thường có thể được bọc trong một phần tử
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
33 hoặc một phần tử
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
37 được tạo kiểu phù hợp tùy thuộc vào việc chúng chứa nội dung đơn hay nhiều dòng

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
1

Thuộc tính

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
38 của phần tử HTML
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
35 nhận dạng dữ liệu được mã hóa. Lưu ý rằng bạn không cần nhập
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
40 hoặc
grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
41 nữa, vì vậy hãy tiếp tục và xóa chúng khỏi đầu tệp

Như mọi khi, bạn muốn làm cho tập lệnh của mình có thể chạy được bằng cách đọc nội dung từ đầu vào tiêu chuẩn. Bạn cũng bọc nội dung HTML đã tạo bằng một số bản soạn sẵn trong hàm

grandparent:
  parent:
    child: {name: Bobby}
    sibling: {'name': "Molly"}
42 mới

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
2

HTML này sử dụng Phông chữ Google được nhúng để có giao diện dễ chịu hơn. Kiểu CSS nội tuyến loại bỏ các dấu đầu dòng khỏi danh sách không có thứ tự thông thường vì bạn sử dụng các dấu đầu dòng cho ánh xạ khóa-giá trị. Tuy nhiên, danh sách được đánh dấu rõ ràng là trình tự sử dụng dấu gạch ngang trước mỗi mục. Mapping keys are displayed in bold font, and multiline strings preserve the whitespace

Khi bạn chạy tập lệnh đối với một số dữ liệu thử nghiệm, tập lệnh sẽ xuất ra một đoạn mã HTML mà bạn có thể chuyển hướng đến một tệp cục bộ mà bạn có thể mở tệp này bằng trình duyệt web mặc định của mình

  • các cửa sổ
  • Linux
  • hệ điều hành Mac

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
3

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
4

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
5

Trang kết quả sẽ cho phép bạn mở rộng và thu gọn các cặp khóa-giá trị riêng lẻ một cách tương tác khi được xem trước trong trình duyệt web

Cây HTML tương tác của các nút YAML

Lưu ý cách trình duyệt web hiển thị hình ảnh được mã hóa Base64 mô tả khuôn mặt cười. Bạn sẽ tìm thấy mã cuối cùng trong phần có thể thu gọn bên dưới

Mã nguồn hoàn chỉnhHiển thị/Ẩn

{
    "text": "2022-01-16",
    "numbers": {8, 13, 5},
    "image": b"GIF87a\x08\x00\x08\x00\xf0\x00…",
    "pair": ["black", "white"],
    "center_at": [3.14+2.72j],
    "person": 
}
6

Được rồi, đó là tất cả khi phân tích tài liệu YAML ở cấp độ thấp bằng thư viện PyYAML. Các hàm

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
75 và
grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
77 tương ứng hoạt động theo cách khác bằng cách lấy một chuỗi các sự kiện hoặc nút gốc tương ứng và biến chúng thành một biểu diễn YAML. Nhưng bạn sẽ hiếm khi cần sử dụng chúng

Sự kết luận

Bây giờ bạn biết nơi tìm pin bị thiếu trong Python để đọc và viết tài liệu YAML. Bạn đã tạo công cụ đánh dấu cú pháp YAML và bản xem trước YAML tương tác trong HTML. Đồng thời, bạn đã tìm hiểu về các tính năng mạnh mẽ và nguy hiểm có trong định dạng dữ liệu phổ biến này và cách tận dụng chúng với Python

Trong hướng dẫn này, bạn đã học cách

  • Đọc và viết tài liệu YAML bằng Python
  • Tuần tự hóa các loại dữ liệu tùy chỉnh và tích hợp sẵn của Python thành YAML
  • Đọc tài liệu YAML một cách an toàn từ các nguồn không đáng tin cậy
  • Kiểm soát phân tích tài liệu YAML ở cấp độ thấp hơn

Để lấy mã nguồn cho các ví dụ trong hướng dẫn này, hãy theo liên kết bên dưới

Nhận mã nguồn. Nhấp vào đây để lấy mã nguồn mà bạn sẽ sử dụng để làm việc với YAML trong Python

Đánh dấu là đã hoàn thành

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Gửi cho tôi thủ thuật Python »

Giới thiệu về Bartosz Zaczyński

Bartosz là người hướng dẫn bootcamp, tác giả và lập trình viên đa ngôn ngữ yêu thích Python. Anh ấy giúp sinh viên của mình tiếp cận công nghệ phần mềm bằng cách chia sẻ kinh nghiệm thương mại hơn một thập kỷ trong ngành CNTT

» Thông tin thêm về Bartosz

Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Aldren

Geir Arne

kate

leodanis

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bậc thầy Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Có bao nhiêu ví dụ về kết xuất YAML?

Sau đây là 30 ví dụ mã của yaml. bãi rác []. Bạn có thể bỏ phiếu cho những cái bạn thích hoặc bỏ phiếu cho những cái bạn không thích và chuyển đến dự án gốc hoặc tệp nguồn bằng cách nhấp vào các liên kết phía trên mỗi ví dụ. Bạn cũng có thể muốn kiểm tra tất cả các chức năng/lớp có sẵn của mô-đun yaml hoặc thử chức năng tìm kiếm

Các kiểu dữ liệu YAML khác nhau là gì?

YAML natively supports three basic data types. vô hướng [chẳng hạn như chuỗi, số nguyên và số float], danh sách và mảng kết hợp. Phần mở rộng tên tệp được đề xuất chính thức cho các tệp YAML đã được. khoai mỡ. Có hai mô-đun trong Python cho YAML. PyYAML và ruamel. khoai mỡ. Trong hướng dẫn này, chúng tôi sử dụng cái cũ

Làm cách nào để tuần tự hóa danh sách Python thành tệp YAML?

Phương thức kết xuất tuần tự hóa một đối tượng Python thành luồng YAML. #. /usr/bin/python import yaml users = [ {'name'. 'John Doe', 'nghề nghiệp'. 'người làm vườn'}, {'tên'. 'Lucy Black', 'nghề nghiệp'. 'giáo viên'}] in [yaml. dump [users]] Trong ví dụ này, chúng ta có một danh sách các từ điển. We serialize the list into YAML format with the dump method

What happens when you dump a dictionary in PyYaml?

When calling yaml. dump [] to dump a dictionary loaded by a prior call to yaml. load [] . PyYAML naively ignores all input formatting – including comments, ordering, quoting, and whitespace. Discarded like so much digital refuse into the nearest available bit bucket

Chủ Đề