Làm cách nào để tạo tệp yml trong Python?

Tạo tệp YAML yêu cầu hiểu biết cơ bản về YAML và lý do nó được sử dụng làm tệp cấu hình trong Kubernetes, Ansible, CircleCI, v.v.

Tệp YAML là gì?

YAML hoặc 'Yet Another Markup Language' là ngôn ngữ tuần tự hóa dữ liệu mà con người có thể đọc được. Nó được thiết kế để con người có thể đọc được và cũng hiệu quả để phân tích cú pháp

Đặc tả YAML được viết vào năm 2006 bởi David Preshing, người tạo ra PHP Markdown, người muốn có một ngôn ngữ đánh dấu phổ quát để con người dễ đọc và viết, nhưng vẫn cho phép mật độ thông tin đáng kể và cân bằng hợp lý giữa thời gian máy cần thiết

Trên đây là 3 cách tạo File YAML mới

  1. Nhận tệp mẫu Cấu hình YAML, chẳng hạn như mẫu tệp Ansible Play. Đây là triển khai nginx. khoai mỡ
  2. Sử dụng Trình soạn thảo văn bản hoặc công cụ Trực tuyến để tạo Cú pháp/Cấu trúc YAML
  3. Tạo tệp từ URL YAML

1. Sử dụng mẫu YAML

YAML chủ yếu được sử dụng cho các tệp cấu hình. Vì vậy, để tránh nhầm lẫn, hãy tìm đúng mẫu cấu hình YAML cho Kubernetes, Ansible hoặc CircleCI

Dưới đây là một ví dụ về tệp triển khai cấu hình nginx Kubernetes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Sử dụng công cụ trình xác thực YAML này để xác thực YAML

https. // làm đẹp mã. org/yaml-validator

Khi dữ liệu tệp được xác thực, hãy lưu tệp với phần mở rộng là. khoai mỡ. Phần này giúp tạo tệp YAML hợp lệ

Mở công cụ YAML Formatter từ liên kết bên dưới

https. // làm đẹp mã. org/yaml-beautifier
hoặc
https. // bộ định dạng json. org/yaml-parser

Sao chép và Dán Dữ liệu YAML được đề cập trong Tùy chọn 1 trong Công cụ nhập liệu của công cụ trực tuyến

Tải xuống tệp này bằng biểu tượng tải xuống được đề cập trên khu vực nhập bên phải. Nó sẽ tải xuống tệp YAML

https này. // làm đẹp mã. org/yaml-beautifier đã hỗ trợ xác thực YAML. Điều này sẽ tạo một tệp YAML mới và sẽ cho phép tải xuống

Bây giờ nếu bạn đã có tài liệu hoặc tệp YAML, bạn có thể tải nó lên công cụ này và sửa đổi hoặc xóa một vài đối tượng, một mảng YAML và tải xuống tệp YAML hợp lệ và đã cập nhật

Công cụ này cũng giúp tạo YAML từ tệp văn bản. Tải lên tệp văn bản bằng nút tải lên tệp và YAML sẽ tự động được xác thực và làm đẹp

3. Tạo tệp từ URL YAML

Nhà phát triển cần làm việc với dữ liệu và tệp nằm trên máy chủ đám mây và hiện nay 95% web và ứng dụng được lưu trữ trên AWS, Azure, Google Cloud hoặc Digital Ocean

Nhà phát triển có thể sử dụng URL từ xa để lưu và chỉnh sửa tệp YAML

Dưới đây là một số mẫu của URL YAML. Bây giờ hãy nhấp vào các mẫu YAML này

Khi liên kết này được mở, hãy sử dụng lưu dưới dạng chức năng của trình duyệt và lưu. Nó sẽ tạo tệp YAML và lưu nó trên thiết bị của bạn

Cách tạo tệp YAML trong linux

sử dụng tiếng vang

echo "apiVersion: apps/v1" > config.yml

Sử dụng cảm ứng

touch config.yml

Tôi hy vọng bài viết này giúp bạn hiểu các cách cơ bản để tạo hoặc tạo các tệp YAML hợp lệ và làm đẹp chúng

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 từ phần hướng dẫn 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 các tài liệu XML trong JavaScript chậm và tẻ nhạt vì XML đã sửa, 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 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. Ngoài ra, việc sử dụng các mô hình xử lý XML khác—[, , hoặc ]—cũng sẽ ảnh hưởng đến hiệu suất

Việc triển khai sang một bên, cú pháp linh hoạt, tự do và phức tạp của YAML khiến cho việc phân tích cú pháp và tuần tự hóa chậm nhất cho đến nay. Ở phía bên kia của quang phổ, bạn sẽ tìm thấy JSON, ngữ pháp của nó có thể phù hợp với danh thiếp. Ngược lại, tài liệu ngữ pháp riêng của YAML tuyên bố rằng việc tạo một trình phân tích cú pháp tuân thủ đầy đủ đã được chứng minh là gần như không thể

Sự thật thú vị. yaml chính thức. trang web org được viết dưới dạng tài liệu YAML hợp lệ

Khi nói đến kích thước tài liệu, JSON lại là người chiến thắng rõ ràng. Mặc dù các dấu ngoặc kép, dấu phẩy và dấu ngoặc nhọn thừa chiếm không gian quý giá nhưng bạn có thể xóa tất cả khoảng trắng giữa các thành phần riêng lẻ. Bạn có thể làm tương tự với các tài liệu XML, nhưng nó sẽ không khắc phục được chi phí mở và thẻ đóng. YAML nằm ở đâu đó ở giữa bằng cách có kích thước tương đối trung bình

Về mặt lịch sử, XML đã có sự hỗ trợ tốt nhất trên nhiều loại công nghệ. JSON là một định dạng trao đổi toàn diện không thể đánh bại để truyền dữ liệu trên Internet. Vì vậy, ai sử dụng YAML và tại sao?

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

Công dụng thực tế của YAML

Như đã lưu ý trước đó, YAML chủ yếu được đánh giá cao về khả năng đọc của nó, điều này làm cho nó trở nên hoàn hảo để lưu trữ tất cả các loại dữ liệu cấu hình ở định dạng mà con người có thể đọc được. Nó trở nên đặc biệt phổ biến đối với các kỹ sư DevOps, những người đã xây dựng các công cụ tự động hóa xung quanh nó. Một vài ví dụ về các công cụ như vậy bao gồm

  • ansible. Sử dụng YAML để mô tả trạng thái mong muốn của cơ sở hạ tầng từ xa, quản lý cấu hình và điều phối các quy trình CNTT
  • Docker Soạn. Sử dụng YAML để mô tả các vi dịch vụ bao gồm ứng dụng Dockerized của bạn
  • Kubernetes. Sử dụng YAML để xác định các đối tượng khác nhau trong cụm máy tính để sắp xếp và quản lý

Ngoài ra, một số công cụ, thư viện và dịch vụ đa năng cung cấp cho bạn tùy chọn định cấu hình chúng thông qua YAML, mà bạn có thể thấy thuận tiện hơn các định dạng dữ liệu khác. Ví dụ: các nền tảng như CircleCI và GitHub thường chuyển sang YAML để xác định các quy trình tích hợp, triển khai và phân phối [CI/CD] liên tục. Đặc tả OpenAPI cho phép tạo sơ khai mã dựa trên mô tả YAML của API RESTful

Ghi chú. Tài liệu về khung ghi nhật ký của Python đề cập đến YAML mặc dù thực tế là ngôn ngữ này không hỗ trợ YAML nguyên bản

Có thể bạn sẽ quyết định áp dụng YAML trong dự án tương lai của mình sau khi hoàn thành hướng dẫn này

Cú pháp YAML

YAML lấy cảm hứng từ các định dạng dữ liệu và ngôn ngữ khác mà bạn có thể đã nghe nói đến trước đây. Có lẽ yếu tố nổi bật và quen thuộc nhất trong cú pháp của YAML là thụt lề khối của nó, giống với mã Python. Khoảng trắng hàng đầu trên mỗi dòng xác định phạm vi của một khối, loại bỏ nhu cầu về bất kỳ ký tự hoặc thẻ đặc biệt nào để biểu thị nơi bắt đầu hoặc kết thúc

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

Tài liệu mẫu này xác định một cây phả hệ vớ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": 
}
7 là phần tử gốc, phần tử con trực tiếp của nó là phần tử
{
    "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, phần tử này có hai phần tử con với thuộc tí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": 
}
9 ở mức thấp nhất trong cây. Bạn có thể coi mỗi phần tử là một câu lệnh mở đầu, theo sau là dấu hai chấm [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
10] trong Python

Ghi chú. Đặc tả YAML cấm sử dụng tab để thụt đầu dòng và coi việc sử dụng chúng là lỗi cú pháp. Điều này trùng khớp với khuyến nghị của Python PEP8 về việc ưu tiên khoảng trắng hơn các tab

Đồng thời, YAML cho phép bạn tận dụng cú pháp khối nội tuyến thay thế mượn từ JSON. Bạn có thể viết lại cùng một tài liệu theo cách sau

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
2

Lưu ý cách bạn có thể kết hợp các khối thụt lề và khối nội tuyến trong một tài liệu. Ngoài ra, bạn có thể đặt cả thuộc tính và giá trị của chúng trong dấu ngoặc đơn [

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
11] hoặc dấu ngoặc kép [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
12] nếu bạn muốn. Làm như vậy sẽ kích hoạt một trong hai phương pháp nội suy của , nếu không thì phương pháp này sẽ được thoát bằng dấu gạch chéo ngược khác [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
13] cho bạn. Dưới đây, bạn sẽ tìm thấy Python tương đương với YAML

YAMLPythonDescription_______114

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
15Các chuỗi không được trích dẫn được phân tích cú pháp theo nghĩa đen để các chuỗi thoát như
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
16 trở thành
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
17.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
18
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
19Các chuỗi trích dẫn đơn chỉ nội suy dấu nháy đơn kép [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
00], nhưng không nội suy các chuỗi thoát truyền thống như
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
16.
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
02
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
14Các chuỗi trích dẫn kép [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
12] nội suy các chuỗi thoát như
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
16,
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
06 hoặc
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
07, được biết đến từ ngôn ngữ lập trình C, nhưng không phải là dấu nháy đơn kép [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
00]

Đừng lo lắng nếu điều đó có vẻ khó hiểu. Dù sao thì bạn cũng sẽ muốn chỉ định các chuỗi ký tự không được trích dẫn trong YAML. Một ngoại lệ đáng chú ý là khai báo một chuỗi mà trình phân tích cú pháp có thể hiểu sai thành kiểu dữ liệu sai. Ví dụ:

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
09 được viết mà không có bất kỳ dấu ngoặc kép nào có thể được coi là Boolean Python

Ba cấu trúc dữ liệu cơ bản trong YAML về cơ bản giống như trong Perl, từng là ngôn ngữ kịch bản phổ biến. Họ là những người sau đây

  1. vô hướng. Các giá trị đơn giản như số, chuỗi hoặc Booleans
  2. Mảng. Chuỗi vô hướng hoặc các bộ sưu tập khác
  3. Băm. Mảng kết hợp, còn được gọi là bản đồ, từ điển, đối tượng hoặc bản ghi bao gồm các cặp khóa-giá trị

Bạn có thể xác định một đại lượng YAML tương tự như một đại lượng tương ứng. Đây là vài ví dụ

Kiểu dữ liệuYAMLNull

{
    "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 [Trước 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]Số nguyên
{
    "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 [Trước YAML 1. 2.
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
22]Dấu phẩy động
{
    "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"
        }
    }
}
26Chuỗi
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
27Ngày và giờ
{
    "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

Bạn có thể viết các từ dành riêng trong YAML bằng chữ thường [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
10], chữ hoa [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
32] hoặc chữ hoa tiêu đề [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
33] để phân tích chúng thành loại dữ liệu mong muốn. Bất kỳ biến thể trường hợp nào khác của những từ như vậy sẽ được coi là văn bản thuần túy. Hằng số
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
10 hoặc bí danh dấu ngã [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
11] của nó cho phép bạn nêu rõ việc thiếu giá trị, nhưng bạn cũng có thể để trống giá trị để có tác dụng tương tự

Ghi chú. Kiểu gõ ẩn trong YAML này có vẻ tiện lợi, nhưng nó giống như chơi với lửa và nó có thể gây ra sự cố nghiêm trọng trong các trường hợp cạnh. Kết quả là, YAML 1. 2 đã bỏ hỗ trợ cho một số chữ tích hợp sẵn như

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

Các chuỗi trong YAML giống như danh sách Python hoặc mảng JSON. Họ sử dụng cú pháp dấu ngoặc vuông tiêu chuẩn [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
38] trong chế độ khối nội tuyến hoặc dấu gạch ngang ở đầu [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
39] ở đầu mỗi dòng khi chúng được thụt vào khố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
2

Bạn có thể giữ các mục trong danh sách của mình ở cùng mức thụt đầu dòng như tên thuộc tính của chúng hoặc thêm nhiều khoảng thụt lề hơn nếu điều đó cải thiện khả năng đọc cho bạn

Cuối cùng, YAML có các giá trị băm tương tự như các đối tượng Python hoặc JavaScript. Chúng được tạo thành từ các khóa, còn được gọi là tên thuộc tính hoặc thuộc tính, theo sau là dấu hai chấm [

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
10] và một giá trị. Bạn đã thấy một vài ví dụ về hàm băm YAML trong phần này rồi, nhưng đây là một ví dụ liên quan hơ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
4

Bạn vừa xác định một người, John Doe, người đã kết hôn với Jane Smith và có hai con, Bobby và Molly. Lưu ý cách danh sách trẻ em chứa các đối tượng ẩn danh, không giống như, ví dụ, người phối ngẫu được xác định theo thuộc tính có tên

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
41. Khi các đối tượng ẩn danh hoặc không có tên xuất hiện dưới dạng các mục trong danh sách, bạn có thể nhận ra chúng theo thuộc tính của chúng, được căn chỉnh bằng ký tự gạch ngang mở đầu [
{
    "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

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

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. Chúng thường không cần thiết nhưng có thể giúp bạn xác định khóa ghép từ bộ sưu tập khác hoặc khóa chứa các ký tự dành riêng. Trong trường hợp này, bạn muốn xác định các phím trống để tạo cấu trúc dữ liệu đã đặt, tương đương với ánh xạ không có phím

Ngoài ra, bạn có thể sử dụng thẻ

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
54 để nhúng các tệp nhị phân được mã hóa Base64, chẳng hạn như hình ảnh hoặc các tài nguyên khác, các tệp này sẽ trở thành phiên bản của trong Python. Các thẻ có tiền tố là
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
56 được cung cấp bởi PyYAML

Tài liệu YAML ở trên sẽ dịch sang từ điển Python sau

________số 8

Lưu ý cách thức, với sự trợ giúp của các thẻ YAML, trình phân tích cú pháp đã biến các giá trị thuộc tính thành các loại dữ liệu Python khác nhau, bao gồm một chuỗi, một tập hợp, một đối tượng byte, một bộ, một số phức và thậm chí là một thể hiện của lớp tùy chỉnh

Các tính năng mạnh mẽ khác của YAML là các ký tự neo và bí danh, cho phép bạn xác định một phần tử một lần và sau đó tham chiếu phần tử đó nhiều lần trong cùng một tài liệu. Các trường hợp sử dụng tiềm năng bao gồm

  • Sử dụng lại địa chỉ giao hàng để lập hóa đơn
  • Luân phiên các bữa ăn trong thực đơn
  • Bài tập tham khảo trong chương trình đào tạo

Để khai báo một ký tự neo, mà bạn có thể coi là một biến được đặt tên, bạn sẽ sử dụng ký hiệu dấu và [

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
57], trong khi để hủy đăng ký ký hiệu đó sau này, bạn sẽ sử dụng ký hiệu dấu hoa thị [
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
58]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
1

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 trong khi 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

Ngược lại với vô hướng dòng chảy, vô hướng khối cho phép thay đổi cách xử lý , , hoặc. 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 ứng dụng 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 số 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ó

Đầu tiên, tạo một tập lệnh Python mẫu để in JSON trên đầu ra tiêu chuẩn

{
    "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ự thành đị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 đề xuất để 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ề 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

Việc giới thiệu tham số bổ sung này là một thay đổi đột phá dẫn đến nhiều lời phàn nàn từ những người bảo trì phần mềm phụ thuộc vào 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 PyYAML chính thức cũng như 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 đã xê-ri hóa 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

Đ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. Để giúp bạn không phải gỡ lỗi mã cơ bản, bạn sẽ tìm thấy thông tin quan trọng nhất về cách tải tài liệu bằng PyYAML trong phần này

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

Nếu bạn muốn hiệu suất phân tích cú pháp tốt nhất có thể, thì bạn cần phải nhập thủ công lớp trình nạp phù hợp và chuyển nó vào hàm chung

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
92, như minh họa ở trên. 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 ClassAnchor, 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

So sánh các tính năng của Bộ tải

Dưới đây, bạn sẽ nhận được một minh họa nhanh về các tính năng được đề cập ở trên. Đầu tiên, nhập mô-đun

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
89 và xem ví dụ về neo và bí danh

>>>

%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

Bạn xác định một điểm neo,

%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, gần địa chỉ giao hàng và sau đó sử dụng lại địa chỉ đó cho hóa đơn với sự trợ giúp của bí danh,
%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. Do đó, bạn chỉ phải chỉ định địa chỉ một lần. Tính năng này hoạt động với tất cả các loại trình tải

Ví dụ tiếp theo cho thấy một trong các thẻ YAML tiêu chuẩn đang hoạ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
6

Theo mặc định, các chữ số như

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
23 được coi là số float, nhưng bạn có thể yêu cầu chuyển đổi loại thành chuỗi bằng thẻ
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
52. Hầu như tất cả các trình tải đều tôn trọng các thẻ YAML tiêu chuẩn. Ngoại lệ duy nhất là 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
00, đại diện cho các chuỗi vô hướng cho dù bạn có gắn thẻ hay không

Để tận dụng các thẻ PyYAML do thư viện cung cấp, hãy 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
11 hoặ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
05 vì chúng là trình tải duy nhất có thể xử lý các thẻ dành riêng cho 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
7

Thẻ

%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 trong ví dụ trên chuyển đổi danh sách nội tuyến thành bộ dữ liệu Python. Truy cập vào tài liệu PyYAML để biết đầy đủ, nhưng hãy đảm bảo kiểm tra chéo với tài liệu này, vì tài liệu có thể không được cập nhật

Hầu hết các trình tải đều thông minh trong việc giải tuần tự hóa vô hướng thành các loại phụ trợ, cụ thể hơn một chuỗi, danh sách hoặc từ điển 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
8

Tại đây, bạn có nhiều loại, bao gồ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
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
36, phiên bản
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
77,
%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 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
39. Xin nhắc lạ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 là lớp trình tải duy nhất luôn coi tất cả các đại lượng vô hướng là chuỗi

Giả sử bạn muốn giải tuần tự hóa một lớp tùy chỉnh từ YAML, thực hiện lệnh gọi hàm trong mã Python của bạn hoặc thậm chí thực thi lệnh trình bao trong khi phân tích cú pháp YAML. Trong trường hợp đó, tùy 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
05, chấp nhận một số thẻ thư viện đặc biệt. Các trình tải khác đưa ra một ngoại lệ hoặc bỏ qua các thẻ đó. Bây giờ bạn sẽ tìm hiểu thêm về các thẻ PyYAML

Khám phá các tính năng không an toàn của Loaders

PyYAML cho phép bạn tuần tự hóa và giải tuần tự hóa bất kỳ đối tượng Python có thể chọn nào bằng cách nhấn vào giao diện của nó. Hãy nhớ rằng điều này cho phép thực thi mã tùy ý, vì bạn sẽ sớm phát hiện ra. Tuy nhiên, nếu bạn không quan tâm đến việc ảnh hưởng đến tính bảo mật của ứng dụng, thì khả năng này có thể khá tiện lợi

Thư viện cung cấp một số thẻ YAML được công nhận bở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
05 để hoàn thành việc tạo đố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
    
    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

Tất cả chúng phải được theo sau bởi một tên đủ điều kiện của lớp để khởi tạo, bao gồm tên gói và mô-đun. Thẻ đầu tiên yêu cầu ánh xạ các cặp khóa-giá trị, theo kiểu luồng hoặc kiểu khối. Đây là một ví dụ

%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

Hai thẻ còn lại phức tạp hơn vì mỗi thẻ có hai loại. Tuy nhiên, hai thẻ gần như giống hệt nhau 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
44 ủy quyền xử lý cho
%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. Sự khác biệt duy nhất 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
44 gọi phương thức đặc biệt trên lớp đã chỉ định mà không gọi , trong khi
%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 gọi chính lớp đó, đây là điều bạn sẽ muốn trong hầu hết các trường hợp

Một hương vị của cú pháp cho phép thiết lập trạng thái ban đầu của đối tượng thông qua một danh sách, như vậy

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

Cả hai kiểu đều đạt được hiệu quả tương tự bằng cách gọi 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
50 trong 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
53 với hai giá trị được truyền dưới dạng đối số vị trí. Ngoài ra, bạn có thể sử dụng cú pháp dài dòng hơn một chút cho phép bạn kết hợp vị trí và , trong số một số thủ thuật nâng cao hơn được trình bày ngắn gọn

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

Điều này sẽ vẫn 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
50 trên lớp của bạn, nhưng một trong các đối số sẽ được chuyển thành đối số từ khóa. Trong mọi trường hợp, bạn có thể định nghĩa 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
53 theo cách thủ công hoặc bằng cách tận dụng các lớp dữ liệu trong Python

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

Cú pháp ngắn gọn này sẽ khiến Python tạo trình khởi tạo lớp cũng như một số phương thức khác mà bạn phải tự viết mã

Lưu ý rằng bạn có thể 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
45 đối với bất kỳ đối tượng có thể gọi nào, bao gồm các hàm thông thường và chỉ định các đối số để chuyển. Điều này cho phép bạn thực thi một trong các chức năng tích hợp sẵn, chức năng tùy chỉnh hoặc thậm chí là chức năng cấp mô-đun mà PyYAML sẽ sẵn sàng nhập cho bạn. Đó là một lỗ hổng bảo mật lớn. Hãy tưởng tượng sử dụng mô-đun
%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 hoặ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
58 để chạy lệnh shell truy xuất khóa SSH riêng của bạn nếu bạn đã xác định một khóa

>>>

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

Không khó để thực hiện một yêu cầu HTTP với dữ liệu bị đánh cắp thông qua mạng khi đối tượng được tạo. Kẻ xấu có thể sử dụng thông tin này để truy cập các tài nguyên nhạy cảm bằng danh tính của bạn

Đôi khi, các thẻ này bỏ qua đường dẫn tạo đối tượng bình thường, đây là điển hình của cơ chế tuần tự hóa đối tượng nói chung. Giả sử bạn muốn tải một đối tượng người dùng từ YAML và biến nó thành một thể hiện của lớp sau

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

Bạn đặt 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
59 trong một tệp nguồn riêng có tê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
60 để sắp xếp mọi thứ. Đối tượng người dùng chỉ có một thuộc tính—tên. Bằng cách chỉ sử dụng một thuộc tính và triển khai trình khởi tạo một cách rõ ràng, bạn sẽ có thể quan sát cách PyYAML gọi các phương thức riêng lẻ

Khi bạn quyết định sử dụng thẻ

%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 trong YAML, thì thư viện sẽ 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
49 mà không có bất kỳ đối số nào và không bao giờ 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
50. Thay vào đó, nó thao tác trực tiếp thuộc tí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
64 của đối tượng mới tạo của bạn, thuộc tính này có thể có một số tác dụng không mong muốn

>>>

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

Mặc dù chắc chắn bạn đã tạo một phiên 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
59 mới nhưng nó không được khởi tạo đúng cách vì thuộc tí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
66 bị thiếu. Tuy nhiên, nó có 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
67 bất ngờ, không tìm thấy ở đâu trong nội dung lớp

Bạn có thể khắc phục điều này bằng cách thêm một khai báo vào lớp của mình, cấm tự động thêm hoặc xóa các thuộc tính sau khi đối tượng tồn tại trong bộ nhớ

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

Bây giờ, đối tượng người dùng của bạn sẽ không có thuộc tính nào cả. Bởi vì không 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
64 vốn có, thư viện quay lại gọi từng cặp khóa-giá trị trên đối tượng trống. Điều này đảm bảo rằng chỉ các thuộc tính được liệt kê trong
%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 mới đi qua

Điều này thật tuyệt, nhưng nếu 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
59 chấp nhận một đối số mật khẩu thì sao? . Còn về, chẳng hạn như bộ mô tả tệp hoặc kết nối cơ sở dữ liệu thì sao?

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

Bạn giải mã tên người dùng được duy trì bằng cách sử dụng mật mã ROT-13 nguyên thủy, giúp xoay các ký tự theo mười ba vị trí trong bảng chữ cái. Tuy nhiên, để mã hóa nghiêm túc, bạn sẽ phải nhìn xa hơn thư viện tiêu chuẩn. Lưu ý rằng bạn cũng có thể sử dụng a từ mô-đun tích hợp nếu bạn muốn lưu trữ mật khẩu một cách an toàn

Đây là một cách để tải trạng thái được mã hóa của bạn từ YAML

>>>

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

Miễn là bạn đã xác định 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
74, nó sẽ luôn được ưu tiên và cho phép bạn kiểm soát việc thiết lập trạng thái của đối tượng. Đó là lý do tại sao bạn có thể khôi phục tên gố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
77, từ văn bản được mã hóa ở trên

Trước khi tiếp tục, điều đáng chú ý là PyYAML cung cấp thêm hai thẻ không an toà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
    
    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

Cái đầu tiên cho phép bạn tải một tham chiếu đến một đối tượng Python, chẳng hạn như một lớp, một hàm hoặc một biến, trong mã của bạn. Thẻ thứ hai cho phép tham chiếu một mô-đun Python nhất định. Trong phần tiếp theo, bạn sẽ xem xét các nguồn dữ liệu khác nhau mà PyYAML cho phép bạn tải tài liệu từ đó

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

Tải tài liệu từ chuỗi, tệp hoặc luồng

Khi bạn chọn lớp trình tải hoặc sử dụng một trong các hàm tốc ký, bạn không bị giới hạn chỉ phân tích chuỗi.

{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
91 và các hàm khác do PyYAML đưa ra chấp nhận một đối số duy nhất, đó là một luồng ký tự hoặc byte phổ biến. Các ví dụ phổ biến nhất của các luồng như vậy là các chuỗi và đối tượng Python
{
    "person": {
        "dateOfBirth": "1969-12-31",
        "firstName": "John",
        "lastName": "Doe",
        "married": true,
        "spouse": {
            "dateOfBirth": null,
            "firstName": "Jane",
            "lastName": "Doe"
        }
    }
}
55

>>>

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

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
20

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ự thực hiện chuyển mã thích hợp bằng các phương thức 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

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
21

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ư bộ đệm văn bản trong bộ nhớ hoặc luồng nhị phân

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
22

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 đối số mà bạn có thể lặp lại

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
23

Các tài liệu riêng lẻ phải bắt đầu bằng dấu ba gạch ngang [_______571] 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 giao diện 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

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
24

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 kết xuất nội dung. 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ó

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
25

Khi được gọi với một đối số duy nhất, hàm trả về một chuỗi đại diện cho đối tượng được tuần tự hóa. 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 tin hoặc bất kỳ. 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

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
26

Khi bạn mở một tệp ở chế độ văn bản, thì đó luôn là một cách tốt để. 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 muốn 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ử

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
27

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

>>>

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
28

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à chức năng duy nhất được sử dụng ngầm vì tất cả các chức năng 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 trình bao bọc ủy quyền cho

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
16 có phần sau đây, tiết lộ các đối số vị trí của chúng

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
29

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í 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

Boolean FlagÝ 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
25Thích kiểu dòng chảy hơn kiểu khối.
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 [_______572].
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 các 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____740
%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

%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
20

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

%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
21

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

%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
22

Đố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 đó

%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
23

Để 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

>>>

%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

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 ________ 762 không an toàn ở hậu trường, điều này lợi dụng thẻ ________ 763. Đó 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

>>>

%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
25

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

>>>

%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
26

Đầ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. Một thuộc tính sẽ đại diện cho thẻ YAML tùy chỉnh gắn với lớp của bạn, trong khi thuộc tính thứ hai sẽ là lớp trình tải để sử dụng. 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 sang 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

>>>

%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

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. Điều này bao gồm hầu hết các trường hợp sử dụng và cho phép bạn tập trung vào dữ liệu hơn là phần trình bày của nó. 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
71Sự kiện✔️
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

Hàm viếtInputVí dụ

grandparent:
  parent:
    child:
      name: Bobby
    sibling:
      name: Molly
75Sự kiện
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ỗ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

>>>

%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

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 đó

%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
29

Đó 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

>>>

%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
40

Khéo léo. 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 thư viện của bên thứ ba hoặc 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àu sắcTrọ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

%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
41

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 đượ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ừ và trình bày nó trên luồng đầu ra tiêu chuẩ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
42

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

%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

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

>>>

%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

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

%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

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à
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
200, trong khi ánh xạ khóa-giá trị tận dụng danh sách mô tả [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
201], chứa các thuật ngữ xen kẽ [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
202] và định nghĩa [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
203]. Đâ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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
204 để 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
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
205

%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
46

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

>>>

%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
47

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
204

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

%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
48

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
207 và
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
208. 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ý

%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

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,

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
209, mà bạn sẽ thêm vào sau. Sau đó, bạn nối thẻ HTML tương ứng với sự kiện hiện tại và cập nhật lại ngữ cảnh

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

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

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ả

Bạn có thể tùy chọn biến mô-đun Python của mình thành một tập lệnh thực thi bằng cách thêm vào ở dưới cùng

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

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

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

Lệnh

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
211 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
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
205 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

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

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ử

>>>

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

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ử con 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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
215

>>>

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
216,
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
217 và
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
218], bạn có thể tự động hóa quá trình truyền tải của chúng bằng hàm đệ quy

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
219, 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 đó

>>>

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
220 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 thẻ toàn cầu YAML, chẳng hạn như
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
221, vì vậy bạn có thể trích xuất bit cuối cùng sau dấu hai chấm thứ hai [
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
10]

Sửa đổi hàm 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 hàm

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
223 mới

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
224 và
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
225 mới được giới thiệu trong Python 3. 10 bằng cú pháp 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
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
226 đơ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 tham gia phiên thông dịch tương tác của mình

>>>

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

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
227 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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
228 yêu cầu một
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
217 được lặp lại với một , trong khi
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
230 lặp lại các khóa và giá trị của một
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
218. Đâ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
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
216, thì bạn thay thế nó bằng một phần tử
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
233. Các loại nút khác được bọc trong thẻ
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
234 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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
235 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 gói trong một phần tử
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
233 hoặc một phần tử
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
237 đượ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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
238 của phần tử HTML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
235 nhận dạng dữ liệu được mã hóa. Lưu ý rằng bạn không cần nhập
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
240 hoặc
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
241 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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
242 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. Các phím ánh xạ được hiển thị bằng phông chữ đậm và các chuỗi nhiều dòng giữ nguyên khoảng trắng

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

{
    "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

Phần 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. 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

Tệp Yml trong Python là gì?

YAML [YAML Ain't Markup Language] là ngôn ngữ tuần tự hóa dữ liệu mà con người có thể đọc được . Nó thường được sử dụng cho các tệp cấu hình, nhưng nó cũng được sử dụng trong lưu trữ dữ liệu [e. g. đầu ra gỡ lỗi] hoặc truyền [e. g. tiêu đề tài liệu].

Làm cách nào để tải YAML bằng Python?

Làm theo hướng dẫn bên dưới. .
Mở kho lưu trữ PyYAML GitHub
Nhấp vào phần mã và tải xuống tệp ZIP
Giải nén hoặc Giải nén kho lưu trữ Zip
Mở dấu nhắc lệnh hoặc thiết bị đầu cuối
Thay đổi thư mục PyYAML nơi giải nén tệp zip
Chạy một thiết lập python. lệnh cài đặt py để cài đặt PyYAML

Làm cách nào để tạo một tệp bằng Python?

Cách tạo tệp bằng Python. Trong Python, bạn sử dụng hàm open[] với một trong các tùy chọn sau – "x" hoặc "w" – để tạo tệp mới . "x" – Tạo. lệnh này sẽ tạo một tệp mới khi và chỉ khi không có tệp nào tồn tại với tên đó, nếu không nó sẽ trả về lỗi.

YAML có được xây dựng bằng Python không?

Tuy nhiên, Python thiếu hỗ trợ tích hợp sẵn 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 định dạng này .

Chủ Đề