Khóa học Phát triển Python Nâng cao
Chương
>
Cấp độ
Các mô-đun tuần tự hóa
Mô-đun Cấu trúc
Mục tiêu
Thiết lập phân chia dữ liệu cuối cùng cho vùng đất nông nghiệp mới sử dụng module struct.
Cuối hành trình có một trạm dịch vụ quản lý vùng đất nông nghiệp mới đã được xây dựng và các loại cây trồng đã được trồng. Tại đây chúng ta sẽ kiểm tra và xử lý dữ liệu cho các loại cây trồng đã được trồng và sản lượng dự kiến của vùng đất nông nghiệp. Giống như các cấp độ khác trong chương này, chúng ta sẽ làm việc với việc tuần tự hóa và giải tuần tự hóa dữ liệu, giới thiệu một module cuối cùng có tên là module struct.
Module struct giới thiệu một loạt các hàm tuần tự hóa đóng gói dữ liệu dưới dạng nhị phân, khác với các module mà chúng ta đã làm việc trước đó, tuy nhiên, bạn có quyền kiểm soát lớn hơn về cách cấu trúc dữ liệu cả khi nó được tuần tự hóa và sau này khi giải tuần tự hóa, làm cho nó trở nên linh hoạt hơn các module khác. Sử dụng import struct để truy cập các hàm sau đây mà chúng ta sẽ sử dụng để xử lý dữ liệu:
struct.calcsize(): Xác định số byte được đóng gói của một chuỗi định dạng nhất định, nó nhận một (1) đối số là định dạng mà bạn muốn kiểm tra kích thước byte của nó. Các định dạng mà chúng ta sẽ sử dụng là:- integer: biểu diễn dưới dạng
'i'là định dạng cho dữ liệu biểu diễn bằng số nguyên - float: biểu diễn dưới dạng
'f'là định dạng cho dữ liệu biểu diễn bằng số thập phân - double: biểu diễn dưới dạng
'd'là định dạng cho dữ liệu biểu diễn bằng số thập phân phức tạp hơn khi định dạng float không đủ.
- integer: biểu diễn dưới dạng
struct.pack(): Tuần tự hóa dữ liệu dưới dạng nhị phân, đóng gói theo một định dạng bạn chọn. Bạn có thể nhận hai (2) hoặc nhiều đối số, bao gồm định dạng bạn muốn sử dụng và các giá trị bạn muốn tuần tự hóa. Các định dạng là những định dạng đã được liệt kê trước đó và bạn phải thêm chúng tương ứng với số lượng đối số bạn cung cấp.struct.unpack(): Giải tuần tự hóa dữ liệu nhị phân đã được đóng gói, nhận hai (2) đối số, định dạng mà nó cần so sánh với định dạng khi dữ liệu được tuần tự hóa, và đối số thứ hai là dữ liệu đã được tuần tự hóa.struct.iter_unpack(): Giải tuần tự hóa dữ liệu nhị phân đã được đóng gói, hoạt động giống nhưstruct.unpack()nhưng lặp qua từng khối dữ liệu riêng lẻ thông qua việc sử dụng vòng lặp.struct.pack_into(): Phiên bản nâng cao củastruct.pack(), nhận bốn (4) đối số bao gồm định dạng bạn muốn sử dụng, bộ đệm dữ liệu mà bạn muốn chèn dữ liệu vào, vị trí trong bộ đệm mà bạn muốn dữ liệu chiếm chỗ, và cuối cùng là dữ liệu bạn đang đóng gói.struct.unpack_from(): Phiên bản nâng cao củastruct.unpack(), nhận ba (3) đối số: định dạng bạn muốn sử dụng, bộ đệm dữ liệu bạn muốn giải nén và cuối cùng là vị trí trong bộ đệm mà bạn muốn giải nén. Điều này cho phép bạn giải nén các phần cụ thể của dữ liệu.
Đi bộ đến dấu X ánh sáng tại trạm dịch vụ và đối diện bàn làm việc, tạo ba (3) biến có tên: integer, float và double. Chúng ta sẽ sử dụng chúng để kiểm tra kích thước tính bằng byte của mỗi định dạng bằng cách sử dụng hàm struct.calcsize(). Đối với biến integer sử dụng hàm với 'i' làm đối số, đối với biến float sử dụng hàm với 'f' làm đối số và cuối cùng với biến double sử dụng hàm với 'd' làm đối số. Ví dụ: integer = struct.calcsize('i'). Thêm ba (3) biến này vào hàm write() đã được viết sẵn.
Đi đến dấu X màu vàng và sử dụng hàm read() để thu thập dữ liệu trên vùng đất nông nghiệp mới, lưu ý các điểm dữ liệu và định dạng cho các loại trồng trọt sắp tới, cụ thể là: Resources, Size và Estimate. Sau khi ghi chú dữ liệu này, đi đến dấu X ánh sáng trên thảm xanh và tạo một biến có tên blue_data.
Với biến blue_data lưu trữ giá trị của hàm struct.pack(), thiết lập các đối số là định dạng và các giá trị bạn đã ghi chú trước đó. Khi viết định dạng, bạn phải “đóng gói” các loại định dạng thành một đơn vị duy nhất. Ví dụ, định dạng số nguyên được ký hiệu là 'i' như đã nêu trước đó, nếu bạn thêm ba số nguyên, bạn sẽ ghi là 'iii'. Tương tự, nếu bạn thêm một số nguyên, một số float và một số double, nó sẽ được viết là 'ifd'. Khi thêm dữ liệu, bạn đặt chúng riêng lẻ làm các đối số. Dưới đây là một ví dụ tổng quan:
data_1 = 8 # là một số nguyên data_2 = 2.25 # là một số float data_3 = 900.702938103 # là một số double blue_data = struct.pack('ifd', data_1, data_2, data_3)
Hàm struct.pack() cho phép rất nhiều sự linh hoạt, cho phép bạn đặt cách bạn muốn định dạng dữ liệu và cho phép bạn tuần tự hóa nhiều điểm dữ liệu cùng lúc, theo ý bạn. Thêm dữ liệu đã đọc trước đó sử dụng ví dụ ở trên làm cơ sở. Sử dụng hàm display() với blue_data làm đối số để xem dữ liệu đã được đóng gói.
Đi đến dấu X tối trên thảm xanh và đối diện bảng điều khiển, tạo một biến có tên blue_unpack và lưu trữ giá trị của hàm struct.unpack(), thêm cùng định dạng đã sử dụng để đóng gói dữ liệu và biến blue_data làm các đối số. Định dạng được viết theo cùng cách như hàm struct.pack(), để bạn có thể giải tuần tự hóa dữ liệu theo cùng cách như khi bạn đã tuần tự hóa nó. Sử dụng hàm write() với blue_unpack làm đối số để kiểm tra dữ liệu bạn đã đóng gói trước đó.
Tại cùng vị trí, chúng ta cũng sẽ sử dụng hàm struct.iter_unpack(), nó nhận đúng các đối số giống như struct.unpack() tuy nhiên bây giờ nó được định dạng thành một vòng lặp for, điều này cho phép chúng ta lặp qua dữ liệu thay vì chỉ đơn giản là in tất cả ra. Hàm được viết như sau:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
Chúng ta sẽ sử dụng hàm speak() để hiển thị các giá trị, đối với các đối số bị thiếu trong hàm struct.iter_unpack(), thêm các đối số tương tự như đã sử dụng với struct.unpack() vì đây là những biến thể của cùng một hàm, về mặt cách sử dụng.
Đi đến dấu X màu vàng trên thảm đỏ và đối diện bàn làm việc, sử dụng hàm read() để xem lại số lượng cây trồng. Ghi chú tất cả số lượng và định dạng cho mỗi loại cây trồng. Đi đến dấu X ánh sáng trên thảm đỏ và tạo một đối tượng có tên buffer, và gán giá trị của bytearray(16). Đây là một tập hợp các byte mà chúng ta có thể truy cập trước khi lưu dữ liệu, đối với mục đích của chúng ta, nó hoạt động như một ngân hàng dữ liệu nơi bạn có thể lưu trữ dữ liệu một cách thủ công. Con số 16 làm đối số là độ dài của số byte mà bạn có thể lưu trữ trong đối tượng buffer.
Sử dụng hàm struct.pack_into() để chèn dữ liệu vào đối tượng buffer mà bạn đã tạo. Không cần tạo một biến để lưu trữ giá trị của hàm vì hàm này sẽ chèn trực tiếp các giá trị vào đối tượng buffer. Chúng ta sẽ sử dụng hàm cho mỗi giá trị cây trồng mà bạn đã ghi chú và điền các đối số tương ứng.
Ví dụ, đối với giá trị cây trồng đầu tiên được cung cấp, bạn sẽ được cung cấp định dạng của nó, vị trí byte và số lượng của nó. Thêm định dạng cho đối số đầu tiên, vị trí bạn muốn tuần tự hóa các byte, trong trường hợp này là buffer. Đối với đối số thứ ba, đặt vị trí bạn muốn thêm giá trị bên trong buffer, định dạng xác định số byte được sử dụng nên hãy cẩn thận để đóng gói dữ liệu chưa được chiếm chỗ. Cuối cùng, thêm giá trị bạn muốn tuần tự hóa và đóng gói vào đối tượng buffer.
struct.pack_into('i', buffer, 0, 82)
Đối tượng buffer có 16 byte như đã nêu trước đó, trong mã code được cung cấp ở trên, định dạng số nguyên có 4 byte và được chèn tại vị trí 0. Điều này có nghĩa là sau khi dữ liệu được chèn vào buffer chỉ còn lại 12 byte trống với vị trí 0-3 đã được chiếm bởi giá trị được cung cấp, trong trường hợp này là 82. Thực hiện điều này cho tất cả các điểm dữ liệu cây trồng đã đọc và ghi chú, tổng cộng có ba (3) loại. Sử dụng hàm display() và thêm buffer để hiển thị dữ liệu đã tuần tự hóa.
Đi đến dấu X tối trên thảm đỏ và đối diện bảng điều khiển, tại đây chúng ta sẽ giải tuần tự hóa dữ liệu để kiểm tra nội dung nhằm đảm bảo lưu trữ đúng. Tạo ba biến có tên: lettuce, carrots và melons, chúng ta sẽ giải nén dữ liệu của từng điểm dữ liệu một cách riêng lẻ. Với mỗi biến lưu trữ giá trị của hàm struct.unpack_from() và đặt các đối số sử dụng cùng dữ liệu mà bạn đã ghi chú để đóng gói. Đối với đối số đầu tiên, đặt định dạng, đối số thứ hai thêm đối tượng buffer là vị trí để giải nén và cuối cùng thêm vị trí trong buffer mà bạn muốn giải nén. Ví dụ:
lettuce = struct.unpack_from('i', buffer, 0)
Dữ liệu này tương ứng với ví dụ đóng gói trước đó đang được giải nén, làm tương tự cho hai biến còn lại và chèn lettuce, carrots và melons vào hàm write() đã được viết sẵn để hoàn thành cấp độ.