หลักสูตรการพัฒนาด้วย Python ขั้นสูง
บทที่
>
ระดับ
โมดูลการซีเรียลไลซ์
โมดูลโครงสร้าง
วัตถุประสงค์
ตั้งค่าการแจกแจงข้อมูลขั้นสุดท้ายสำหรับฟาร์มใหม่โดยใช้โมดูล struct
ปลายทางของถนนมีสถานีบริการที่บริหารจัดการฟาร์มใหม่ที่สร้างเสร็จแล้วและพืชที่ปลูกเสร็จแล้ว ที่นี่เราจะตรวจสอบและประมวลผลข้อมูลสำหรับพืชที่ปลูกไปแล้วและผลผลิตที่คาดการณ์ของฟาร์ม เช่นเดียวกับระดับอื่น ๆ ในบทนี้ เราจะทำงานกับการทำซีเรียลไลซ์และดีซีเรียลไลซ์ข้อมูล โดยแนะนำโมดูลสุดท้ายชื่อว่า struct module
โมดูล struct แนะนำฟังก์ชันการซีเรียลไลซ์หลายฟังก์ชันที่บรรจุข้อมูลในรูปแบบไบนารี ซึ่งแตกต่างจากโมดูลอื่น ๆ ที่เราได้ทำงานด้วย อย่างไรก็ตาม คุณจะมีการควบคุมที่มากขึ้นว่าเราสามารถจัดโครงสร้างข้อมูลได้อย่างไรทั้งในขั้นตอนที่ทำซีเรียลไลซ์และในขั้นตอนที่ทำดีซีเรียลไลซ์ในภายหลัง ซึ่งทำให้มีความยืดหยุ่นมากกว่าโมดูลอื่นๆ ใช้ import struct เพื่อเข้าถึงฟังก์ชันต่อไปนี้ที่เราจะใช้ประมวลผลข้อมูล:
struct.calcsize(): ใช้กำหนดจำนวนไบต์ที่ถูกบรรจุในสตริงรูปแบบที่กำหนด โดยรับอาร์กิวเมนต์หนึ่ง (1) ตัว คือรูปแบบที่คุณต้องการตรวจสอบขนาดไบต์ รูปแบบที่เราจะใช้มีดังนี้:- integer: แสดงด้วย
'i'เป็นรูปแบบสำหรับข้อมูลที่แสดงเป็นจำนวนเต็ม - float: แสดงด้วย
'f'เป็นรูปแบบสำหรับข้อมูลที่แสดงเป็นตัวเลขทศนิยม - double: แสดงด้วย
'd'เป็นรูปแบบสำหรับข้อมูลที่แสดงเป็นตัวเลขทศนิยมที่ซับซ้อนมากขึ้นเมื่อรูปแบบ float ไม่เพียงพอ
- integer: แสดงด้วย
struct.pack(): ทำซีเรียลไลซ์ข้อมูลในรูปแบบไบนารี โดยบรรจุในรูปแบบที่คุณเลือก คุณสามารถรับอาร์กิวเมนต์สอง (2) ตัวหรือมากกว่านั้น ซึ่งได้แก่รูปแบบที่คุณต้องการใช้และค่าที่คุณต้องการซีเรียลไลซ์ รูปแบบต่างๆ คือรูปแบบที่ได้กล่าวถึงก่อนหน้านี้และคุณต้องเพิ่มให้สอดคล้องกับจำนวนอาร์กิวเมนต์ที่คุณเพิ่มstruct.unpack(): ดีซีเรียลไลซ์ข้อมูลไบนารีที่บรรจุไว้ รับอาร์กิวเมนต์สอง (2) ตัว คือรูปแบบที่ต้องเปรียบเทียบกับรูปแบบที่ใช้ในการซีเรียลไลซ์ และตัวที่สองคือข้อมูลที่ถูกซีเรียลไลซ์struct.iter_unpack(): ดีซีเรียลไลซ์ข้อมูลไบนารีที่บรรจุไว้ ทำงานเหมือนกับstruct.unpack()แต่จะวนลูปผ่านแต่ละบล็อกข้อมูลทีละตัวโดยใช้การวนลูปstruct.pack_into(): เป็นเวอร์ชันขั้นสูงของstruct.pack()รับอาร์กิวเมนต์สี่ (4) ตัว ได้แก่ รูปแบบที่คุณต้องการใช้, บัฟเฟอร์ข้อมูลที่คุณต้องการใส่ข้อมูลเข้าไป, ตำแหน่งในบัฟเฟอร์ที่คุณต้องการให้ข้อมูลครอบครอง และสุดท้ายคือข้อมูลที่คุณจะบรรจุstruct.unpack_from(): เป็นเวอร์ชันขั้นสูงของstruct.unpack()รับอาร์กิวเมนต์สาม (3) ตัว คือ รูปแบบที่คุณต้องการใช้, บัฟเฟอร์ข้อมูลที่คุณต้องการดีซีเรียลไลซ์ และสุดท้ายตำแหน่งในบัฟเฟอร์ที่คุณต้องการดีซีเรียลไลซ์ วิธีนี้ช่วยให้คุณสามารถดีซีเรียลไลซ์เฉพาะส่วนของข้อมูลได้
เดินไปที่เครื่องหมาย X สีสว่างในสถานีบริการและหันหน้าไปที่เคาน์เตอร์ สร้างตัวแปรสาม (3) ตัวชื่อว่า: integer , float และ double เราจะใช้ตัวแปรเหล่านี้เพื่อตรวจสอบขนาดในไบต์ของแต่ละรูปแบบ โดยใช้ฟังก์ชัน struct.calcsize() สำหรับตัวแปร integer ให้ใช้ฟังก์ชันพร้อมอาร์กิวเมนต์ 'i' สำหรับตัวแปร float ให้ใช้ฟังก์ชันพร้อมอาร์กิวเมนต์ 'f' และสำหรับตัวแปร double ให้ใช้ฟังก์ชันพร้อมอาร์กิวเมนต์ 'd' ยกตัวอย่างเช่น: integer = struct.calcsize('i') เพิ่มตัวแปรทั้งสาม (3) ลงในฟังก์ชัน write() ที่เขียนไว้แล้ว
เดินไปที่เครื่องหมาย X สีทองและใช้ฟังก์ชัน read() เพื่อรวบรวมข้อมูลเกี่ยวกับฟาร์มใหม่ จดบันทึกจุดข้อมูลและรูปแบบสำหรับการใช้งานในอนาคต ได้แก่: Resources , Size และ Estimate เมื่อจดบันทึกข้อมูลเสร็จแล้ว ให้เดินไปที่เครื่องหมาย X สีสว่างบนพรมสีฟ้าและสร้างตัวแปรชื่อ blue_data
ในตัวแปร blue_data ให้เก็บค่าที่ได้จากฟังก์ชัน struct.pack() โดยกำหนดอาร์กิวเมนต์คือ รูปแบบและค่าที่คุณจดบันทึกไว้ก่อนหน้านี้ เมื่อเขียนรูปแบบ คุณต้อง "บรรจุ" รูปแบบข้อมูลเข้าเป็นหน่วยเดียว ยกตัวอย่างเช่น รูปแบบของจำนวนเต็มถูกกำหนดเป็น 'i' ตามที่ได้อธิบายไว้ก่อนหน้านี้ หากคุณเพิ่มข้อมูลจำนวนเต็มสามค่า คุณจะเพิ่มเป็น 'iii' ในทำนองเดียวกัน หากคุณเพิ่มจำนวนเต็ม หนึ่ง float และหนึ่ง double จะเขียนเป็น 'ifd' เมื่อเพิ่มข้อมูล ให้ใส่ค่าลงไปทีละอาร์กิวเมนต์ นี่คือตัวอย่างโดยรวม:
data_1 = 8 # is an integer data_2 = 2.25 # is a float data_3 = 900.702938103 # is a double blue_data = struct.pack('ifd', data_1, data_2, data_3)
ฟังก์ชัน struct.pack() อนุญาตให้มีความยืดหยุ่นมากมาย ช่วยให้คุณสามารถกำหนดวิธีการจัดรูปแบบข้อมูลและทำซีเรียลไลซ์ข้อมูลจุดต่าง ๆ ได้หลายจุดในครั้งเดียวตามที่คุณต้องการ เพิ่มข้อมูลที่อ่านไว้ก่อนหน้านี้โดยใช้ตัวอย่างข้างต้นเป็นฐาน ใช้ฟังก์ชัน display() พร้อมอาร์กิวเมนต์ blue_data เพื่อแสดงข้อมูลที่ถูกบรรจุ
เดินไปที่เครื่องหมาย X สีเข้มบนพรมสีน้ำเงินและหันหน้าไปที่เทอร์มินัล สร้างตัวแปรชื่อ blue_unpack และเก็บค่าที่ได้จากฟังก์ชัน struct.unpack() โดยเพิ่มอาร์กิวเมนต์คือ รูปแบบเดียวกับที่ใช้ในการบรรจุข้อมูลและตัวแปร blue_data รูปแบบเขียนในลักษณะเดียวกับฟังก์ชัน struct.pack() เพื่อให้คุณสามารถดีซีเรียลไลซ์ข้อมูลในลักษณะเดียวกับที่คุณทำการซีเรียลไลซ์ข้อมูลครั้งแรก ใช้ฟังก์ชัน write() พร้อมอาร์กิวเมนต์ blue_unpack เพื่อตรวจสอบข้อมูลที่คุณได้บรรจุก่อนหน้านี้
ที่ตำแหน่งเดียวกันนี้ เราจะใช้ฟังก์ชัน struct.iter_unpack() ด้วย ซึ่งรับอาร์กิวเมนต์เหมือนกับ struct.unpack() แต่ตอนนี้ถูกจัดรูปแบบเป็นลูป for ซึ่งช่วยให้เราสามารถวนลูปผ่านข้อมูลได้แทนที่จะเขียนออกมาทั้งหมด ฟังก์ชันถูกเขียนดังนี้:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
เราจะใช้ฟังก์ชัน speak() เพื่อแสดงค่า สำหรับอาร์กิวเมนต์ที่ขาดในฟังก์ชัน struct.iter_unpack() ให้เพิ่มอาร์กิวเมนต์เดียวกันกับที่ใช้ใน struct.unpack() เนื่องจากเป็นรูปแบบการใช้งานที่เหมือนกัน
เดินไปที่เครื่องหมาย X สีทองบนพรมสีแดงและหันหน้าไปที่เคาน์เตอร์ ใช้ฟังก์ชัน read() เพื่อตรวจสอบปริมาณพืช จดบันทึกปริมาณทั้งหมดและรูปแบบสำหรับพืชแต่ละชนิด เดินไปที่เครื่องหมาย X สีสว่างบนพรมสีแดงและสร้างอ๊อบเจ็กต์ชื่อ buffer และเพิ่มค่าที่ได้จาก bytearray(16) นี่คือการเก็บรวบรวมไบต์ที่เราสามารถเข้าชมได้ก่อนที่จะเติมข้อมูล สำหรับวัตถุประสงค์ของเรา มันทำงานเหมือนธนาคารข้อมูลที่คุณสามารถเก็บข้อมูลด้วยตนเอง ตัวเลข 16 ในฐานะอาร์กิวเมนต์คือความยาวของจำนวนไบต์ที่คุณสามารถเก็บในอ๊อบเจ็กต์ buffer
ใช้ฟังก์ชัน struct.pack_into() เพื่อเติมอ๊อบเจ็กต์ buffer ที่คุณสร้างไว้ ไม่จำเป็นต้องสร้างตัวแปรเพื่อเก็บค่าที่ได้จากฟังก์ชัน เพราะฟังก์ชันนี้จะใส่ค่าลงในอ๊อบเจ็กต์ buffer โดยตรง เราจะใช้ฟังก์ชันนี้สำหรับแต่ละค่าของพืชที่คุณได้จดบันทึกไว้
ยกตัวอย่างเช่น สำหรับค่าพืชตัวแรกที่ให้มา คุณจะได้รับรูปแบบ, ตำแหน่งไบต์ และปริมาณ ให้เพิ่มรูปแบบเป็นอาร์กิวเมนต์แรก, ตำแหน่งที่คุณต้องการซีเรียลไลซ์ไบต์ซึ่งในกรณีนี้คือ buffer สำหรับอาร์กิวเมนต์ที่สาม กำหนดตำแหน่งที่คุณต้องการเพิ่มค่าใน buffer โดยรูปแบบจะกำหนดไบต์ที่ถูกใช้ไป ดังนั้นจึงต้องใช้ในการบรรจุข้อมูลที่ยังไม่ถูกครอบครอง สุดท้ายเพิ่มค่าที่คุณต้องการซีเรียลไลซ์และบรรจุลงในอ๊อบเจ็กต์ buffer
struct.pack_into('i', buffer, 0, 82)
อ๊อบเจ็กต์ buffer มีขนาด 16 ไบต์ตามที่ได้กล่าวไว้ในตอนแรก ในโค้ดที่ให้ไว้ข้างต้น รูปแบบของจำนวนเต็มใช้ 4 ไบต์และถูกแทรกที่ตำแหน่ง 0 ซึ่งหมายความว่าเมื่อข้อมูลถูกแทรกลงใน buffer จะเหลือเพียง 12 ไบต์ใน buffer ที่ว่างอยู่ โดยตำแหน่ง 0-3 ถูกครอบครองด้วยค่าที่ให้ไว้ ในกรณีนี้คือ 82 ทำสิ่งนี้สำหรับจุดข้อมูลพืชทั้งหมดที่ได้อ่านและจดบันทึกไว้ ซึ่งมีทั้งหมดสาม (3) ค่า ใช้ฟังก์ชัน display() พร้อมเพิ่ม buffer เพื่อแสดงข้อมูลที่ซีเรียลไลซ์แล้ว
เดินไปที่เครื่องหมาย X สีเข้มบนพรมสีแดงและหันหน้าไปที่เทอร์มินัล ที่นี่เราจะทำการดีซีเรียลไลซ์ข้อมูลเพื่อตรวจสอบเนื้อหาเพื่อให้แน่ใจว่าการจัดเก็บถูกต้อง สร้างตัวแปรสามตัวชื่อว่า: lettuce , carrots และ melons เราจะดีซีเรียลไลซ์ข้อมูลของแต่ละจุดข้อมูลทีละตัว สำหรับแต่ละตัวแปร ให้เก็บค่าที่ได้จาก struct.unpack_from() และกำหนดอาร์กิวเมนต์โดยใช้ข้อมูลเดียวกับที่คุณได้จดบันทึกเพื่อซีเรียลไลซ์ข้อมูล สำหรับอาร์กิวเมนต์แรกให้ตั้งค่ารูปแบบ, อาร์กิวเมนต์ที่สองให้เพิ่มอ๊อบเจ็กต์ buffer ซึ่งเป็นตำแหน่งที่จะดีซีเรียลไลซ์ และสุดท้ายเพิ่มตำแหน่งใน buffer ที่คุณต้องการดีซีเรียลไลซ์ตัวอย่างเช่น:
lettuce = struct.unpack_from('i', buffer, 0)
ข้อมูลนี้สอดคล้องกับตัวอย่างการบรรจุก่อนหน้าที่ถูกดีซีเรียลไลซ์ ทำเช่นเดียวกันสำหรับตัวแปรอีกสองตัวและใส่ lettuce , carrots และ melons ลงในฟังก์ชัน write() ที่เขียนไว้แล้วเพื่อให้ระดับสำเร็จ