10 Advanced Python Tricks To Write Faster, Cleaner Code

17-Sep-21

คัมภีร์เทพ IT

See the original english version Click here!

 

นี่คือ 10 เคล็ดลับขั้น Advance เพื่อเขียน Python Code ให้เร็วและ Clean ขึ้น คุณอาจรู้จักสิ่งเหล่านี้มาบ้างแล้ว แต่เชื่อว่ายังมีอีกหลายสิ่งที่ Developer ทุกคนสามารถเรียนรู้เพิ่มเติมได้ จากบทความนี้

1. การใช้ Slotted Classes

ใน Slotted Classes เราจะมีการ Define Field อย่างชัดเจนที่ Class ของเรา ซึ่งสามารถใช้ Field ชื่อ __slots__ ได้ และมันก็มีข้อดี เช่น:

  • Objects ที่สร้างจาก Class จะใช้ Memory น้อยลง
  • เข้าถึง Attributes ของ Class ได้เร็วขึ้น
  • คุณไม่สามารถเพิ่ม Attributes ที่ไม่ถูกต้อง ให้กับ Objects ของ Slotted Class ได้

นี่คือตัวอย่างวิธีการ Define Slotted Class:

ข้อดีอย่างมาก ก็คือ คุณไม่สามารถเพิ่ม Attributes ที่ไม่ถูกต้อง ให้กับ Objects ของ Slotted Class ได้ อย่างเช่น การสะกดผิด ดังด้านล่างนี้ จะทำให้เกิด Error แทนที่จะให้ Python สร้าง Attribute ให้ ซึ่งมันสามารถป้องกันความผิดพลาดได้

สำหรับ Class ขนาดเล็กที่ไม่มี Inheritance ที่ซับซ้อน การใช้ Slots อาจเป็นข้อได้เปรียบ โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการสร้าง Instance ของ Class จำนวนมาก และการใช้ Memory น้อยลง รวมทั้งการเข้าถึง Attribute ที่เร็วขึ้นก็สามารถสร้างความแตกต่างได้เช่นกัน

2. ดู Size ของ Object

ด้วยการใช้ sys.getsizeof() คุณสามารถตรวจสอบการใช้ Memory ของ Python Object ได้ ลองดูข้างล่างนี้:

คุณอาจสงสัยว่า ทำไม List ที่ใหญ่แบบนี้ ถึงมีขนาดเพียงแค่ 48 bytes เท่านั้นเอง

นั่นเป็นเพราะ Range Function มีการ Return Object ที่มีลักษณะเหมือนกับ List เท่านั้น Rage ซึ่งเป็น Generator Object มี Memory ที่มีประสิทธิภาพ มากกว่าการใช้ List ของตัวเลขจริง ๆ มันจะ Generate ตัวเลขใหม่หากจำเป็น แทนที่จะเก็บตัวเลขทั้งหมดจริง ๆ

คุณสามารถพิสูจน์ด้วยตัวคุณเอง โดยใช้ List Comprehension เพื่อสร้าง List ของตัวเลขจริง ๆ จาก Range เดียวกัน:

ดังนั้น ด้วยการลองใช้ sys.getsizeof() คุณจะสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Python และการใช้ Memory ของคุณ

แต่โชคไม่ดี ที่ sys.getsizeof() ใช้งานได้ดีกับ Built-in Data Types เท่านั้น สำหรับ Custom Data Types และ Profiling Tools อื่น ๆ คุณควรลองดู Package ที่เรียกว่า Pympler ซึ่งมี Function ที่เรียกว่า asizeof() คุณสามารถอ่านข้อมูลเพิ่มเติมได้ที่ Pympler Docs

3. ใช้ Tuples แทนการใช้ Lists

Python Tuple เป็น 1 ใน 3 Built-in Sequence Data Types ของ Python ส่วนที่เหลือจะเป็น Lists และ Range Objects สำหรับ Python Tuple จะมีการ Share Properties เป็นจำนวนมากกับ Lists:

  • มันสามารถเก็บค่าได้หลาย ๆ ค่า ภายในตัวแปรเดียว
  • มันจะคงลำดับของ Items ไว้อย่างนั้น ไม่สามารถเปลี่ยนแปลงได้
  • Tuple สามารถมีค่าที่ซ้ำกันได้
  • มันถูกจัดทำ Index แล้ว: คุณสามารถเข้าถึง Items ต่าง ๆ ด้วยตัวเลข
  • Tuple สามารถมีความยาวได้แบบไม่จำกัด

และมันก็มีลักษณะเฉพาะตัว เช่น:

  • Tuple เป็น Immutable ซึ่งทำให้ไม่สามารถเปลี่ยนแปลงได้หากคุณ Define มันแล้ว
  • Tuple ถูก Define โดยการใช้วงเล็บ () แทนที่จะเป็นวงเล็บ []
  • เนื่องจาก Tuple เป็น Immutable และ Hashable พวกมันจึงสามารถทำหน้าที่เป็น Key ใน Dictionary ได้

หากคุณไม่ต้องการที่จะแก้ไขปรับเปลี่ยน Lists ของคุณแล้ว คุณก็น่าจะพิจารณาการใช้ Tuple เนื่องจากมันมีข้อดีหลายเรื่อง พวกมันถูกสร้างได้เร็วกว่า อีกทั้งยังสามารถป้องกัน Behavior ที่ไม่คาดคิดได้ เพราะพวกมันไม่สามารถถูกแก้ไขได้นั่นเอง สิ่งนี้มีประโยชน์อย่างมากโดยเฉพาะเมื่อคุณทำงานเกี่ยวข้องกับ Concurrency ซึ่ง Threads หรือ Processes สามารถเข้าถึง List เดียวกันได้ในช่วงเวลาเดียวกัน

อีกอย่างหนึ่งคือ พวกมันไม่ได้ต้องการ Memory อะไรมากมาย และเพื่อยืนยันสิ่งที่กล่าวมาข้างต้น ลองทำสิ่งนี้ดู:

4. Conditional Statements (Inline if/else)

คุณสามารถใช้โครงสร้าง If..Else แบบสั้น ๆ ให้อยู่ในบรรทัดเดียวกันได้ เพื่อให้ Code มีความกระชับขึ้น และยังทำให้อ่านง่ายขึ้นอีกด้วย:

5. Else Statements และ Loops

เราสามารถใส่ Else Statement ลงใน Python Loop Statement ได้ เรามาดู Syntax พื้นฐานกัน:

หรือเมื่อใช้ While Statement:

ส่วนของ Else จะถูก Execute ตาม Default (เมื่อจบ Iterable) เว้นแต่ว่า Loop จะ 'หยุด' ด้วยคำสั่ง Break

ข้อดีของการใช้คำสั่ง Else คืออะไร?

บ่อยครั้งที่คุณทำอะไรบางอย่างภายใน Loop จนกว่าจะถึงบาง Condition หากมันตรงตาม Condition นั้น คุณจะ Set ค่า Flag บางอย่างขึ้นมา เช่น found = True และทำการ Break Loop ซึ่งจาก Code ดังกล่าว คุณต้องตรวจสอบว่า Flag ได้ถูก Set (if found …) เว้นแต่ว่า คุณจะใช้คำสั่ง Else

ตัวอย่างด้านล่างนี้มาจาก Python Documentation ซึ่งเป็นตัวอย่างการหาจำนวนเฉพาะ โดยแสดงจำนวนเฉพาะออกมาในส่วนของการใช้ Else:

แล้วข้อเสียคืออะไร?

Programmer หลายคนมักไม่ค่อยคาดหวังอะไรใน Else Statement หลังการวน Loop มากนัก โดยเฉพาะอย่างยิ่งเมื่อมาจากภาษาอื่น ๆ ดังนั้น การใช้วิธีการแบบเดิม ๆ ในการทำสิ่งต่าง ๆ อาจทำให้ Code อ่านได้ง่ายกว่าสำหรับคนส่วนใหญ่

6. การ Sort Objects ด้วย Multiple Keys

สมมติว่า เราต้องการที่จะ Sort (เรียงลำดับ) List ของ Dictionaries ต่อไปนี้:

แต่เราไม่เพียงต้องการ Sort มันตาม Name หรือ Age ตัวใดตัวหนึ่ง เราต้องการที่จะ Sort ตามทั้ง 2 Fields ซึ่งใน SQL เราสามารถทำได้ด้วย Query ดังนี้:

ต้องขอบคุณ Python’s Guarantee ที่ทำให้ Sort Function มี Stable Sort Order ซึ่งมีวิธีแก้ปัญหาที่ตรงไปตรงมาสำหรับปัญหานี้ นั่นหมายความว่า Items ที่ถูกเปรียบเทียบว่าพวกมันเท่ากัน ก็จะยังคงลำดับเดิมไว้

เพื่อให้การ Sort ตาม Name และ Age เป็นไปตามที่เราต้องการ เราสามารถทำได้ดังนี้:

ลองสังเกตดูว่า เราจะเรียงลำดับด้วยการทำแบบย้อนขึ้นมา นั่นคือ ก่อนอื่นเราจะจัดเรียงลำดับตาม Age ก่อน จากนั้นก็ค่อยเรียงลำดับตาม Name ด้วยการใช้ operator.itemgetter() จะทำให้เราได้รับ Age และ Name Fields จากแต่ละ Dictionary ภายใน List ด้วยวิธีที่กระชับ

เราจะได้ผลลัพธ์ตามที่เราต้องการ:

จะ Sort ตาม Name ก่อน จากนั้น Age ก็จะถูก Sort ด้วยในกรณีที่ Name เหมือนกัน ดังนั้น คนที่ชื่อ Johns ทั้งหมดที่ถูกจัดกลุ่มไว้ด้วยกัน แล้วก็ Sort ตาม Age

7. Comprehensions

List Comprehension เป็นวิธีที่ดีในการเติม Items ลงใน List โดยไม่ต้องใช้ For-Loop ซึ่ง Syntax พื้นฐานสำหรับ List Comprehension ก็คือ:

ตัวอย่างง่าย ๆ เพื่อเติม Items ลงใน List ด้วยตัวเลขที่เรียงตามลำดับ:

และเนื่องจาก คุณสามารถใช้ Expression ได้ คุณจึงสามารถใช้การคำนวณ เข้าร่วมได้:

หรือแม้แต่ การ Call External Function:

และสุดท้าย คุณสามารถใช้ 'If' เพื่อทำการ Filter List โดยในกรณีนี้ เราจะเก็บเฉพาะค่าที่หารด้วย 2 ลงตัว:

สิ่งนี้สามารถใช้ได้กับ Sets และ Dictionaries ด้วย คุณสามารถดูตัวอย่างอื่น ๆ ได้ในบทความนี้

8. Data Classes

ตั้งแต่ Version 3.7 เป็นต้นมา Python มี Data Classes มาให้ด้วย ซึ่งมันมีข้อดีกว่า Classes ทั่วไปในหลายเรื่อง หรือแม้แต่ทางเลือกอื่น ๆ อย่างการ Return หลาย ๆ Values หรือ Dictionaries:

  • ใน Data Classes ไม่จำเป็นต้องเขียน Code ให้มากมาย
  • คุณสามารถเปรียบเทียบ Data Classes ได้ เนื่องจากคุณสามารถใช้ __eq__ ได้
  • คุณสามารถ Print Data Class เพื่อการ Debug ได้อย่างง่ายดาย เนื่องจากคุณสามารถใช้ __repr__ ได้เช่นกัน
  • ใน Data Classes คุณสามารถใช้ Type Hint ซึ่งช่วยลดโอกาสการเกิด Bug ได้

นี่คือ ตัวอย่างของ Data Class:

คุณสามารถใช้เทคนิค Slotted Class (ในข้อ 1) ร่วมกับ Data Classes ได้ เพื่อสร้าง Data Class ที่มีกลุ่มของ Fields ที่ถูกกำหนดไว้แล้ว

หากคุณต้องการเรียนรู้เพิ่มเติม สามารถดูได้ที่ Tutorial ของ Data Classes นี้

9. การ Merge Dictionaries

ตั้งแต่ Python 3.5 คุณสามารถ Merge Dictionaries ได้ง่ายกว่าเมื่อก่อน และตั้งแต่ Python 3.9 เป็นต้นมา สิ่งต่าง ๆ ก็ดีขึ้นเรื่อย ๆ:

หากมี Keys ที่ซ้ำซ้อนกัน, Key จาก Dictionary แรก จะถูกเขียนทับ (Overwrite)

10. การใช้และรู้จัก Itertools

Itertools เป็น Built-in Library ที่มี Iterator พื้นฐานให้เป็นจำนวนมาก ซึ่งพื้นฐานเหล่านี้สามารถถูกใช้สำหรับ Operations ทั่วไปบางอย่างได้อย่างมีประสิทธิภาพ เป็นไปได้ว่า คุณอาจกำลังเขียนบาง Functions Itertools เพื่อให้ได้ผลลัพธ์ที่คุณต้องการ ดังนั้น มันจึงคุ้มค่าที่คุณควรจะรู้จัก Library นี้

นี่คือ ตัวอย่างบางส่วน:

นี่เป็นเพียงส่วนพื้นฐานบางส่วนเท่านั้น คุณสามารถดู Itertools Recipes ใน Documentation ได้ เนื่องจากเป็นตัวอย่างที่ยอดเยี่ยมเกี่ยวกับสิ่งที่คุณสามารถสร้างได้โดยใช้พื้นฐานเหล่านี้ และถ้าคุณต้องการเรียนรู้เพิ่มเติม ขอแนะนำให้ดู Itertools Tutorial นี้

ที่มา: https://medium.com/

 

 

รับตำแหน่งงานไอทีใหม่ๆ ด้วยบริการ IT Job Alert

 

อัพเดทบทความจากคนวงในสายไอทีทาง LINE ก่อนใคร
อย่าลืมแอดไลน์ @techstarth เป็นเพื่อนนะคะ

เพิ่มเพื่อน

 

บทความล่าสุด