YAML AIN’T MARKUP LANGUAGE (YAML)
YAML là một định dạng cực kỳ phổ biến mà con người có thể đọc được để xây dựng các file cấu hình và lưu trữ dữ liệu. Nó được xây dựng cho các trường hợp sử dụng tương tự như XML nhưng có cú pháp và cấu trúc đơn giản hơn nhiều. Nó sử dụng thụt lề giống như Python để phân biệt các khối thông tin và được xây dựng dựa trên cú pháp JSON nhưng với một loạt các tính năng không có sẵn trong JSON. Nếu bạn đã từng sử dụng Docker hoặc Kubernetes, chắc chắn bạn đã gặp phải các file YAML:
---
interface:
name: GigabitEthernet2
description: Wide Area Network
enabled: true
ipv4:
address:
- ip: 172.16.0.2
netmask: 255.255.255.0
YAML có thể biểu diễn cho một danh sách bằng cách sử dụng ký tự “-“ để xác định các phần tử
---
addresses:
- ip: 172.16.0.2
netmask: 255.255.255.0
- ip: 172.16.0.3
netmask: 255.255.255.0
- ip: 172.16.0.4
netmask: 255.255.255.0
YAML, theo như tên gọi, không phải là một ngôn ngữ đánh dấu giống như JSON hay XML. Với định dạng mang tính tối giản của nó, cả con người và máy đều có thể đọc và hiểu được. Nói chung, định dạng YAML là dễ đọc nhất trong tất cả các định dạng và ngày càng trở nên phổ biến trong các cộng đồng kỹ sư làm việc trong lĩnh vực lập trình. Hình bên dưới là một ví dụ của định dạng YAML.
Hình trên là một đoạn trích ra từ file cấu hình của định dạng YAML. Các thông tin về file host về một người dùng ứng dụng. Người dùng này có tên là john, vị trí văn phòng ở Austin và đóng vai trò là admin.
Các khoảng trắng có ý nghĩa quan trọng trong YAML bởi vì các khoảng trắng này định nghĩa cấu trúc của một file YAML. Tất cả các dữ liệu bên trong một đối tượng đặc biệt thì ở cùng một mức. Trong ví dụ này, đối tượng được tách ra là một người dùng có tên là john. Tất cả các dữ liệu ở cùng mức này là thuộc tính của đối tượng đó. Mức kế tiếp của cách lề bắt đầu bằng thuộc tính location, chỉ ra một đối tượng có hai thuộc tính là city và state. Một cách tiêu biểu, YAML thường dùng hệ thống cách lề với hai khoảng trắng cho mọi loại đối tượng được định nghĩa, nhưng bạn có thể sử dụng hệ thống cách lề theo kiểu bạn quen thuộc.
Chú ý là cách dùng phím TAB là không cho phép trong YAML bởi vì phím TAB được nhận dạng khác nhau bởi các công cụ khác nhau. Trong YAML, các khóa và các giá trị được ngăn cách nhau bằng dấu hai chấm. Điều này làm cho con người dễ đọc và viết. YAML cũng cố gắng áp đặt loại dữ liệu đang sử dụng trong phần giá trị. Nếu có một giá trị là john, YAML sẽ giả sử rằng đó là một chuỗi. Cũng chú ý rằng không có dấu phẩy nào đang kết thúc của các giá trị đang gán cho các khóa. YAML tự động biết khi nào kết thúc của một giá trị.
Để làm việc với YAML bằng Python, bạn cần cài đặt và nhập mô-đun PyYaml. Các đối tượng YAML được chuyển đổi thành dictionary và YAML list tự động trở thành Python list. Hai hàm thực hiện giải thuật này là yaml.load để chuyển đổi từ các đối tượng YAML thành Python và yaml.dump để chuyển đổi các đối tượng Python trở lại YAML. Mô-đun PyYaml mới nhất yêu cầu bạn thêm một đối số để cho nó biết bạn muốn sử dụng loader nào. Đây là biện pháp bảo mật để code của bạn không dễ bị thực thi một cách tùy ý từ file YAML độc hại.
>>>import yaml
>>>with open("yaml_sample.yaml") as data:
>>> yaml_sample = data.read()
>>> yaml_dict = yaml.load(yaml_sample, Loader=yaml.FullLoader)
Như các ví dụ về kiểu dữ liệu từ điển, bạn có thể sửa đổi đối tượng này theo ý thích của mình. Ví dụ: bạn có thể thay đổi tên giao diện thành GigabitEtherenet1
>>> yaml_dict["interface"]["name"] = "GigabitEthernet1"
Và cuối cùng, để lưu lại vào tập tin của bạn,
>>>with open("yaml_sample.yaml", "w") as data:
>>>data.write(yaml.dump(yaml_dict, default_flow_style=False))
Khi bạn phân giải các dữ liệu từ các định dạng dữ liệu, bạn cần biết quá trình chuyển đổi đang thực sự diễn ra như thế nào bên trong code Python của bạn. Trong trường hợp này, các chuỗi từ file YAML sẽ được dịch sang các đối tượng trong Python như thế nào? Có lẽ YAML là một trong những định dạng dữ liệu gần nhất với Python bởi vì nó tương ứng các dữ liệu vào dạng từ điển của Python. Sau đó, bạn có thể thực hiện tất cả các thao tác mạnh trên các dữ liệu này.
Bảng bên dưới sẽ mô tả cách thức một cấu trúc dạng YAML được dịch sang dạng đối tượng của Python. Mặc định, một đối tượng YAML được chuyển sang dạng từ điển Python, một dãy array chuyển sang dạng danh sách và cứ thế tiếp tục.
Khi bạn đã chọn lựa một thư viện mà bạn thấy phù hợp và ưa thích, trong trường hợp này là PyYAML, đầu tiên bạn phải tải thư viện đó vào script của bạn. Bạn làm điều đó bằng câu lệnh đơn giản import yaml ở phần đầu. Lưu ý rằng thư viện PyYAML không có sẵn với Python vì vậy bạn cần đảm bảo là thư viện đã được cài đặt vào hệ thống trước khi import thư viện vào scripts. Nếu thư viện đó chưa được cài đặt trong hệ thống, bạn chỉ cần đơn giản chạy lệnh pip install PyYAML từ màn hình windows để cài đặt.
Hành động kế tiếp là mở file YAML và nạp nó vào đối tượng Python sao cho bạn có thể làm việc với dữ liệu một cách dễ dàng. Bạn làm điều này bằng cách định nghĩa một biến trong Python để phân giải tất cả các thông tin từ file đó. Phương thức yaml.safe_load() được dùng cho mục đích đó.
Để in ra đối tượng Python mà bạn đã phân giải các dữ liệu từ file YAML, hãy dùng mã sau: print(data).
Kết quả phải có dạng như bên dưới:
Bạn có thể thấy là kết quả không phải là rõ ràng nhất. Nó bao gồm tất cả các thông tin trộn lẫn với nhau. Kiểu dữ liệu này giống như là loại từ điển trong Python. Để kiểm tra kiểu dữ liệu của biến đó, hãy dùng code sau:
print(type(data))
Output: <class ‘dict’>
Trong trường hợp này, bạn có thể xác nhận rằng đây là một từ điển Python hợp lệ. Bạn có thể truy cập các thành phần bằng các từ khóa là tên – ví dụ data['user'].
Từ bước này trở đi, tất cả các thao tác bạn làm là trong từ điển Python bên trong đoạn script. Nó không ảnh hưởng đến file YAML.
Bước kế tiếp, bạn muốn xem qua tất cả các vai trò có trong từ điển và in kết quả ra. Bạn thực hiện điều đó bằng cách tạo ra một vòng lặp Python để đi qua tất cả các đối tượng với từ khóa là roles.
Vòng lặp trong ví dụ sẽ cho kết quả là
Admin
User
Như vậy bạn đã mở thành công một file YAML, phân tích các thông tin và đưa vào một biến, duyệt qua tất cả các dữ liệu với các từ khóa và in kết quả mong muốn ra.
Giả sử bạn gặp một tác vụ là thay đổi vị trí của một số người dùng khi họ di chuyển văn phòng tới Dallas. Thay đổi thủ công tất cả các thông tin sẽ rất tốn thời gian. Với mục đích đó, bạn sẽ muốn dùng các đoạn script có sẵn để thực hiện thay đổi trên các người dùng này. Loại dữ liệu đang khảo sát là city, đang được gán giá trị là “Austin”. Thay đổi này cần bạn định vị các khóa bên trong từ điển Python và thay đổi giá trị của nó đến tên thành phố mới.
Cho tới nay, tất cả những gì bạn đang thay đổi là nội dung của từ điển Python bên trong đoạn script. Để lưu vĩnh viễn tất cả các thay đổi, bạn cần phải chuyển ngược loại dữ liệu này vào trở lại file YAML. Trong ví dụ này bạn tạo ra một file YAML mới cho mục đích đó. Theo cách này, về sau bạn có thể so sánh nội dung hai file với nhau và thấy tác động của đoạn script của bạn.
Một cách tương tự, khi bạn mở file, bạn có một phương thức bên trong PyYAML để lưu cấu hình ngược lại một file. Dùng phương thức yaml.dump() bên trong đoạn scripts sẽ giúp dễ dàng thực hiện việc này.
YAML là một định dạng cực kỳ phổ biến mà con người có thể đọc được để xây dựng các file cấu hình và lưu trữ dữ liệu. Nó được xây dựng cho các trường hợp sử dụng tương tự như XML nhưng có cú pháp và cấu trúc đơn giản hơn nhiều. Nó sử dụng thụt lề giống như Python để phân biệt các khối thông tin và được xây dựng dựa trên cú pháp JSON nhưng với một loạt các tính năng không có sẵn trong JSON. Nếu bạn đã từng sử dụng Docker hoặc Kubernetes, chắc chắn bạn đã gặp phải các file YAML:
---
interface:
name: GigabitEthernet2
description: Wide Area Network
enabled: true
ipv4:
address:
- ip: 172.16.0.2
netmask: 255.255.255.0
YAML có thể biểu diễn cho một danh sách bằng cách sử dụng ký tự “-“ để xác định các phần tử
---
addresses:
- ip: 172.16.0.2
netmask: 255.255.255.0
- ip: 172.16.0.3
netmask: 255.255.255.0
- ip: 172.16.0.4
netmask: 255.255.255.0
YAML, theo như tên gọi, không phải là một ngôn ngữ đánh dấu giống như JSON hay XML. Với định dạng mang tính tối giản của nó, cả con người và máy đều có thể đọc và hiểu được. Nói chung, định dạng YAML là dễ đọc nhất trong tất cả các định dạng và ngày càng trở nên phổ biến trong các cộng đồng kỹ sư làm việc trong lĩnh vực lập trình. Hình bên dưới là một ví dụ của định dạng YAML.
Hình trên là một đoạn trích ra từ file cấu hình của định dạng YAML. Các thông tin về file host về một người dùng ứng dụng. Người dùng này có tên là john, vị trí văn phòng ở Austin và đóng vai trò là admin.
Các khoảng trắng có ý nghĩa quan trọng trong YAML bởi vì các khoảng trắng này định nghĩa cấu trúc của một file YAML. Tất cả các dữ liệu bên trong một đối tượng đặc biệt thì ở cùng một mức. Trong ví dụ này, đối tượng được tách ra là một người dùng có tên là john. Tất cả các dữ liệu ở cùng mức này là thuộc tính của đối tượng đó. Mức kế tiếp của cách lề bắt đầu bằng thuộc tính location, chỉ ra một đối tượng có hai thuộc tính là city và state. Một cách tiêu biểu, YAML thường dùng hệ thống cách lề với hai khoảng trắng cho mọi loại đối tượng được định nghĩa, nhưng bạn có thể sử dụng hệ thống cách lề theo kiểu bạn quen thuộc.
Chú ý là cách dùng phím TAB là không cho phép trong YAML bởi vì phím TAB được nhận dạng khác nhau bởi các công cụ khác nhau. Trong YAML, các khóa và các giá trị được ngăn cách nhau bằng dấu hai chấm. Điều này làm cho con người dễ đọc và viết. YAML cũng cố gắng áp đặt loại dữ liệu đang sử dụng trong phần giá trị. Nếu có một giá trị là john, YAML sẽ giả sử rằng đó là một chuỗi. Cũng chú ý rằng không có dấu phẩy nào đang kết thúc của các giá trị đang gán cho các khóa. YAML tự động biết khi nào kết thúc của một giá trị.
Để làm việc với YAML bằng Python, bạn cần cài đặt và nhập mô-đun PyYaml. Các đối tượng YAML được chuyển đổi thành dictionary và YAML list tự động trở thành Python list. Hai hàm thực hiện giải thuật này là yaml.load để chuyển đổi từ các đối tượng YAML thành Python và yaml.dump để chuyển đổi các đối tượng Python trở lại YAML. Mô-đun PyYaml mới nhất yêu cầu bạn thêm một đối số để cho nó biết bạn muốn sử dụng loader nào. Đây là biện pháp bảo mật để code của bạn không dễ bị thực thi một cách tùy ý từ file YAML độc hại.
>>>import yaml
>>>with open("yaml_sample.yaml") as data:
>>> yaml_sample = data.read()
>>> yaml_dict = yaml.load(yaml_sample, Loader=yaml.FullLoader)
Như các ví dụ về kiểu dữ liệu từ điển, bạn có thể sửa đổi đối tượng này theo ý thích của mình. Ví dụ: bạn có thể thay đổi tên giao diện thành GigabitEtherenet1
>>> yaml_dict["interface"]["name"] = "GigabitEthernet1"
Và cuối cùng, để lưu lại vào tập tin của bạn,
>>>with open("yaml_sample.yaml", "w") as data:
>>>data.write(yaml.dump(yaml_dict, default_flow_style=False))
Khi bạn phân giải các dữ liệu từ các định dạng dữ liệu, bạn cần biết quá trình chuyển đổi đang thực sự diễn ra như thế nào bên trong code Python của bạn. Trong trường hợp này, các chuỗi từ file YAML sẽ được dịch sang các đối tượng trong Python như thế nào? Có lẽ YAML là một trong những định dạng dữ liệu gần nhất với Python bởi vì nó tương ứng các dữ liệu vào dạng từ điển của Python. Sau đó, bạn có thể thực hiện tất cả các thao tác mạnh trên các dữ liệu này.
Bảng bên dưới sẽ mô tả cách thức một cấu trúc dạng YAML được dịch sang dạng đối tượng của Python. Mặc định, một đối tượng YAML được chuyển sang dạng từ điển Python, một dãy array chuyển sang dạng danh sách và cứ thế tiếp tục.
| YAML | Python | ||
| object |
|
||
| array |
|
||
| string |
|
||
| number (int) |
|
||
| number (real) |
|
||
| true | true | ||
| false |
|
||
| null | None |
Khi bạn đã chọn lựa một thư viện mà bạn thấy phù hợp và ưa thích, trong trường hợp này là PyYAML, đầu tiên bạn phải tải thư viện đó vào script của bạn. Bạn làm điều đó bằng câu lệnh đơn giản import yaml ở phần đầu. Lưu ý rằng thư viện PyYAML không có sẵn với Python vì vậy bạn cần đảm bảo là thư viện đã được cài đặt vào hệ thống trước khi import thư viện vào scripts. Nếu thư viện đó chưa được cài đặt trong hệ thống, bạn chỉ cần đơn giản chạy lệnh pip install PyYAML từ màn hình windows để cài đặt.
Hành động kế tiếp là mở file YAML và nạp nó vào đối tượng Python sao cho bạn có thể làm việc với dữ liệu một cách dễ dàng. Bạn làm điều này bằng cách định nghĩa một biến trong Python để phân giải tất cả các thông tin từ file đó. Phương thức yaml.safe_load() được dùng cho mục đích đó.
Để in ra đối tượng Python mà bạn đã phân giải các dữ liệu từ file YAML, hãy dùng mã sau: print(data).
Kết quả phải có dạng như bên dưới:
Bạn có thể thấy là kết quả không phải là rõ ràng nhất. Nó bao gồm tất cả các thông tin trộn lẫn với nhau. Kiểu dữ liệu này giống như là loại từ điển trong Python. Để kiểm tra kiểu dữ liệu của biến đó, hãy dùng code sau:
print(type(data))
Output: <class ‘dict’>
Trong trường hợp này, bạn có thể xác nhận rằng đây là một từ điển Python hợp lệ. Bạn có thể truy cập các thành phần bằng các từ khóa là tên – ví dụ data['user'].
Từ bước này trở đi, tất cả các thao tác bạn làm là trong từ điển Python bên trong đoạn script. Nó không ảnh hưởng đến file YAML.
Bước kế tiếp, bạn muốn xem qua tất cả các vai trò có trong từ điển và in kết quả ra. Bạn thực hiện điều đó bằng cách tạo ra một vòng lặp Python để đi qua tất cả các đối tượng với từ khóa là roles.
Vòng lặp trong ví dụ sẽ cho kết quả là
Admin
User
Như vậy bạn đã mở thành công một file YAML, phân tích các thông tin và đưa vào một biến, duyệt qua tất cả các dữ liệu với các từ khóa và in kết quả mong muốn ra.
Giả sử bạn gặp một tác vụ là thay đổi vị trí của một số người dùng khi họ di chuyển văn phòng tới Dallas. Thay đổi thủ công tất cả các thông tin sẽ rất tốn thời gian. Với mục đích đó, bạn sẽ muốn dùng các đoạn script có sẵn để thực hiện thay đổi trên các người dùng này. Loại dữ liệu đang khảo sát là city, đang được gán giá trị là “Austin”. Thay đổi này cần bạn định vị các khóa bên trong từ điển Python và thay đổi giá trị của nó đến tên thành phố mới.
Cho tới nay, tất cả những gì bạn đang thay đổi là nội dung của từ điển Python bên trong đoạn script. Để lưu vĩnh viễn tất cả các thay đổi, bạn cần phải chuyển ngược loại dữ liệu này vào trở lại file YAML. Trong ví dụ này bạn tạo ra một file YAML mới cho mục đích đó. Theo cách này, về sau bạn có thể so sánh nội dung hai file với nhau và thấy tác động của đoạn script của bạn.
Một cách tương tự, khi bạn mở file, bạn có một phương thức bên trong PyYAML để lưu cấu hình ngược lại một file. Dùng phương thức yaml.dump() bên trong đoạn scripts sẽ giúp dễ dàng thực hiện việc này.