Đối tượng kết xuất Python sang yaml

Khi làm việc với các tệp YAML trong Python, có thể bạn đang sử dụng thư viện PyYAML. Điều này rất hữu ích khi lưu trữ các tệp cấu hình, cấu trúc lồng nhau hoặc dữ liệu giống như chuỗi. Điều thú vị về nó là khả năng kết xuất/tải các đối tượng Python [không chỉ int‘s, str‘s, float‘s, list‘s thông thường]. Trong bài viết này, chúng ta sẽ nói về việc tùy chỉnh quy trình lập số sê-ri này và điều chỉnh định dạng kết quả cho phù hợp với nhu cầu của chúng ta

Giả sử chúng ta có một mô hình

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0 được viết với sự trợ giúp của một thư viện tuyệt vời khác có tên là attrs

1
2
3
4
5
6
import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]

Chúng tôi có thể tạo cửa hàng của riêng mình với danh sách người dùng và tuần tự hóa/giải tuần tự hóa nó thành một tệp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]

Thật tuyệt vời khi có một phương pháp thuận tiện như vậy để lưu trữ bất kỳ đối tượng Python nào trong một tệp. Nhưng nhìn vào đầu ra

1
2
- !!python/object:__main__.User {age: 24, name: Misha}
- !!python/object:__main__.User {age: 42, name: Bob}

Nó không phải là thứ tôi mong đợi và nó không phải là thứ có thể dễ dàng chỉnh sửa thủ công mà không vô tình làm hỏng cấu trúc của nó. Những gì chúng tôi muốn thực sự là có một cái gì đó như thế này

1
2
3
4
- name: Misha
age: 24
- name: Bob
age: 42

Cố gắng lùi lại và lưu trữ người dùng của chúng tôi dưới dạng từ điển thông thường cũng không giúp được gì

1
2
3
4
users = [{'name': 'Misha', 'age': 24}, {'name': 'Bob', 'age': 42}]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

Chúng tôi vẫn sẽ có đầu ra hơi khác so với mong muốn

1
2
import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
1

Khá dễ để khắc phục việc chuyển các tham số bổ sung cho hàm kết xuất

import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
2
import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
3

Tại thời điểm này, chúng tôi đã có đầu ra được định dạng độc đáo. Bạn cũng có thể cung cấp đối số

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. YAML cung cấp ba phong cách. trích dẫn kép, trích dẫn đơn và đơn giản [không trích dẫn]. Vượt qua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2 trong trường hợp bạn muốn trích dẫn các mục trong đầu ra của mình
Nhưng đó chỉ dành cho từ điển thông thường và chúng tôi muốn có một đầu ra đẹp như vậy cho các đối tượng tùy chỉnh của mình. Vẫn có định nghĩa kiểu cho mỗi bản ghi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
3. Chúng ta có thể chuyển trách nhiệm tải một thể hiện từ thư viện sang lớp
chính nó. Bằng cách này, lớp của chúng ta sẽ biết cách tạo các thể hiện của nó từ các ký tự thông thường và tệp kết quả sẽ rõ ràng và con người có thể đọc được. Chúng tôi có thể triển khai phương thức
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
4 trên lớp của mình nhưng hy vọng attrs có chức năng
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
5 của riêng nó
Điều tiếp theo chúng ta cần triển khai là lớp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
6 của riêng chúng ta sẽ được truyền cho phương thức
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
7 khi tuần tự hóa các đối tượng
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0. Lớp này hơi phức tạp được kế thừa từ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
9,
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
0,
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
1,
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
2
căn cứ. Nhưng điều duy nhất chúng ta quan tâm là
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
1 quyết định xem đối tượng của chúng ta sẽ trông như thế nào trong đầu ra mục tiêu

import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
4_______2_______5

Chúng tôi cần xác định phương thức đại diện của riêng mình, về cơ bản sẽ tạo một lệnh từ đối tượng của chúng tôi và hơn là gọi triển khai

users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
4 hiện có. Đây là nơi bạn có thể cung cấp logic của riêng mình hoặc gọi một cái gì đó như phương thức
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
5
Sau đó, chúng tôi khai báo lớp kết xuất của chúng tôi, lớp này chỉ là một lớp con của lớp
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
6 và lớp
users = []
user1 = User[name='Misha', age=24]
user2 = User[name='Bob', age=42]

users.append[user1]
users.append[user2]

with open['users.yml', 'w'] as f:
f.write[yaml.dump[users]]

with open['users.yml'] as f:
data = yaml.load[f]

assert len[data] == len[users]
user = data[0]
assert isinstance[user, User]
print[user.name]
7 của chúng tôi. Trình kết xuất an toàn giới hạn khả năng sử dụng tuần tự hóa với các đối tượng Python đơn giản thay vì đối tượng thông thường mạnh mẽ như dưa chua

1
2
3
4
5
6
import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
7

Có mã ở trên tại chỗ, hãy kiểm tra xem nó hoạt động như thế nào với bộ nhớ người dùng của chúng tôi

import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
8
import attr

@attr.s
class User[object]:
name: str = attr.ib[]
age: int = attr.ib[default=0]
9

chúng ta đi đây. Giờ đây, chúng tôi có thể kết xuất/chỉnh sửa/tải người dùng của mình một cách liền mạch trong tệp YAML và chúng tôi có thể viết quy trình tương tự cho bất kỳ đối tượng nào chúng tôi muốn. Tôi sẽ để lại cho bạn bức ảnh về con mèo này và thú cưng của nó, chúc bạn cuối tuần vui vẻ

Chủ Đề