Tutorial

F-String ลูกเล่นใน Python ที่หลาย ๆ คนมองผ่าน

By Arnon Puitrakul - 01 ธันวาคม 2021

F-String ลูกเล่นใน Python ที่หลาย ๆ คนมองผ่าน

หลาย ๆ ครั้งเวลาเราไปอ่าน Code ในเว็บต่าง ๆ แล้วอาจจะเจอการเขียนที่หน้าตาแปลก ๆ ตอนที่เขาพยายาม print ข้อความออกทางหน้าจอ ทำไมมี f อยู่หน้า String อะไรพวกนั้นด้วย แล้วมันได้เหรออะไรแบบนั้น เอาจริง ๆ เห็นครั้งแรกก็ร้องว่า ห่ะ เหมือนกัน แต่พอมาใช้เข้าจริงแล้วมันง่ายมาก ๆ ทำให้เราเขียนแล้วไม่ต้องมานั่งปวดหัวเลย สิ่งนั้นคือ F-String วันนี้เราจะพามาดูกันว่า F-String มันช่วยทำให้เราเขียน Python Script ได้ง่ายขึ้นผ่านท่าไหนบ้าง

ท่า Baseline

>>> a_age = 25
>>> print(a_age)
25

ก่อนเราจะไปลอง F-String เราเริ่มจากท่าปกติกันก่อน สมมุติว่า เราต้องการจะเอาค่าออกทางหน้าจอแบบง่ายที่สุด เราก็สามารถสั่ง Print ออกมาตรง ๆ ได้เลย เพราะคำสั่ง print() มันรับอะไรเข้ามาก็ได้ แล้วมันจะไปเรียก Dunder __str__ เพื่อแปลงเป็น String สำหรับการแสดงผลนั่นเอง

>>> print("Mr.A is " + a_age + " years old.")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str

ทีนี้ถ้าเราต้องการที่จะใส่ข้อความเพิ่มลงไปอีกละ อื้ม... ทำไงดี เราก็บวกมันเลยม่ะ เหมือนที่เราบวก String ปกติ พอเราบวกเข้าไปเท่านั้นแหละ เราก็จะเจอกับ Error ด้านบนเลย เป็นหนึ่งใน Pitfall ที่มือใหม่เจอเลยก็ว่าได้ สาเหตุที่มันทำแบบนี้ไม่ได้ อยากให้ลองดูที่ Error ดี ๆ มันบอกว่า มันสามารถ Concat String กับ String ได้เท่านั้น แต่ที่เรายัดเข้ามา คือ Integer ทำให้มันไม่ได้ แล้วเราจะแก้ปัญหายังไงละ

>>> print("Mr.A is " + str(a_age) + " years old.")
Mr.A is 25 years old.

การแก้ปัญหาคือ ในเมื่อมันต่อ String กับ Integer ไม่ได้ เราก็แปลงให้มันกลายเป็น String สิ ผ่านคำสั่ง str() ที่เราใช้แปลงข้อมูลให้กลายเป็น String ทำให้เมื่อเราเอา String ต่อกับ String มันก็จะผ่านได้นั่นเอง

เราเห็นปัญหาจากการทำแบบนี้มั้ยฮ่ะ ถ้าเกิดว่า เราจะต้องมีการ Format ข้อความที่ซับซ้อนมากขึ้น มีการ Format ตัวแปร เช่น วันที่ ไหนจะตัวแปรต่อกันเยอะ เราก็ต้องบวก ๆ มันไปเรื่อย ๆ เราว่ามันทำให้ Code อ่านยาก และดูซับซ้อนมากเกินไป แล้วเราจะทำยังไงละ ถึงจะทำให้มันง่ายขึ้น

F-String มาแล้วจ้า

>>> print(f"Mr.A is {a_age} years old.")
Mr.A is 25 years old

เราสามารถใช้ F-String ในการแก้ปัญหานี้ได้อย่างง่ายมาก ๆ แบบ ง่ายจริง ๆ ลองดูด้านบนได้ เราไม่ต้องมานั่ง Concat String อะไรให้ งง เลย เราสามารถยัดตัวแปรลงไปได้ตรง ๆ ภายใน String เลย

วิธีการที่เราจะบอกว่ามันคือ F-String คือ เราจะเอาตัว f ไปไว้หน้า String แค่นั้นเลย ส่วนเวลาเราจะใส่ตัวแปรลงไป เราจะต้องมีเครื่องหมายปีกกาคั่นเอาไว้แค่นั้นเลย ก็ทำให้เราใช้งาน F-String ได้แล้ว นอกจากนั้น เรายังสามารถเขียนเป็น Expression ให้มันคำนวณอะไรง่าย ๆ ภายในนั้นได้เลย เช่น เราอาจจะต้องคูณเลขในนั้นเพิ่มอะไรแบบนั้น

บอกเลยว่าลองใช้แล้วจะรู้ว่ามันทำให้ใช้งานได้ง่ายจริง ๆ แค่นี้ว่าเจ๋งแล้วใช่มั้ย เราจะพาไปหาท่าที่เฟี้ยวกว่านี้อีก

Formatting Number

ปกติเวลาเราจะ Print อะไรออกมาจากหน้าจอ เราก็จะต้องมีการ Format มันให้อยู่ในรูปแบบที่พร้อมจะแสดงผลให้กับผู้ใช้ เราไม่สามารถที่จะเอาตัวเลขตรง ๆ มาแสดงได้เลย เพราะมันอ่านยากมากเช่น 1405940204920 กับ 1,405,940,204,920 อันที่ 2 ย่อมอ่านง่ายกว่าแน่ ๆ แต่โดย Default แล้ว Python มันจะเลือกแสดงแบบแรกน่ะสิ ทำให้เราจะต้องแปลงให้มันอยู่ในรูปแบบที่เราต้องการนั่นคือแบบที่ 2 ก่อน

company_value = 1_405_940_204_920
print(format(company_value, ',d'))

โดยปกติ ถ้าเราต้องการตัวเลขในแบบที่ 2 เราสามารถใช้คำสั่ง Format เพื่อแปลงมันก็ได้ หรือถ้าใครอยากเท่ หาทำเยอะ ๆ ก็เขียนเองไปเลยจ้าา แปลงให้เป็น String แล้วค่อย ๆ ซอยจากข้างหลังทีละ 3 ไปเรื่อย ๆ ก็ได้เหมือนกัน ทำทำไมสภาพพพพพพ

>>> print(f"The value of the company is {company_value:,d}")
The value of the company is 1,405,940,204,920

แต่ถ้าเราใช้ F-String เราก็จะเห็นได้เลยว่า เราสามารถที่จะบอก Format ของมันได้ภายในช่องของตัวแปรได้เลย โดยเราจะคั่นชื่อตัวแปรกับ Format ด้วยเครื่องหมาย Colon ส่วน Format เราใส่เป็น ,d ก็คือ เราจะใส่เครื่องหมาย Comma คั่นนะ โดยที่การใส่เราจะใส่โดยอิงจากจำนวนตัวเลข ซึ่งก็คือคั่นทีละ 3 ตัวไปเรื่อย ๆ เลยทำให้ออกมาเป็นอย่างที่เราเห็นด้านบน

แต่ถ้าเราสังเกตดี ๆ เราจะเห็นว่า Syntax ที่ใช้ในการ Format มันเหมือนกันเลยนะ ทั้งข้างบนกับข้างล่าง ใช่แล้วละ เพราะจริง ๆ แล้ว F-String มันก็คือ Shorthand ของ format() นั่นแหละ ทำให้มันใช้ลักษณะการเขียนแบบเดียวกันนั่นเอง ดังนั้นอะไรที่ format() ทำได้ F-String ก็ทำได้เช่นกัน

>>> pi = 3.1415926535897932384
>>> print(f"Pi is {pi:.2f}")
Pi is 3.14

หรือในแง่ของตัวเลขที่เป็นทศนิยม เราก็สามารถที่จะทำให้มันแสดงผลเป็นจำนวนตำแหน่งที่เราต้องการได้ด้วย ผ่านการใช้ Format ตัวอย่างเช่น ด้านบน เราใช้เป็น .2f เราว่าถ้าใครที่เขียนภาษาอื่น ๆ มาน่าจะคุ้นเคยกับการเขียน Format ตัวนี้มาไม่มากก็น้อยแล้วละ จุด กับ f มันเป็นการบอกว่า โอเค เราจะกำหนดจำนวนตำแหน่งของ จำนวนทศนิยม (Float) นะ แล้ว 2 คือจำนวนตำแหน่งที่เราต้องการนั่นเอง ง่ายมาก ๆ เลยใช่มั้ย

Padding Number

อีกหนึ่งตัวอย่างที่เราใช้บ่อยมาก ๆ คือการ Pad Number เช่น เราบอกว่า เรามีตัวเลข 8 แต่เราต้องการให้มันเป็น 008 ตัวอย่างของการเอาไปใช้งานเช่น อาจจะเป็นการ Format เพื่อแสดง Product ID อะไรแบบนั้น มันก็จำเป็นที่จะต้องใช้

def pad_number (number, position) :
    num_str = str(number)
    if len(num_str) >= position :
        return num_str
    else :
        return "0"*(position - len(num_str) + num_str

เมื่อก่อนตอนที่เขียน Python ใหม่ ๆ เลย เราไม่รู้เรื่องการทำ Format มาก่อนเลย เลยเออ นั่งเขียนเองเลย ตอนนั้นก็หาทำใช้ได้อยู่เหมือนกัน จนมารู้จักกับ Built-in Function ก็ค่อยง่ายขึ้นหน่อย ลดการหาทำได้มหาศาลมาก ๆ

>>> product_a = 4
>>> product_b = 100

>>> print(f"Product A : {product_a:03}")
Product A : 004

>>> print(f"Product B : {product_b:03}")
Product B : 100

ในเมื่อวันนี้เราคุยกันเรื่อง F-String ก็คือนี่เลย เราสามารถใช้ 0 แล้วตามด้วยจำนวนตำแหน่งของตัวเลขที่เราต้องการ Pad ได้เลย แค่นี้เราก็พร้อมใช้แล้ว

Table Print

>>> print(f"Product A : {product_a:03}")
Product A : 004

>>> print(f"Product A : {product_a:13}")
Product A :             4

>>> print(f"Product A : {product_a:23}")
Product A :                       4

ถามว่า แล้วเลข 0 คืออะไร เรามาลอง Experiment กันดีกว่า เราจะเห็นจากด้านบนได้ว่า เอ๊ะ มันไม่ใช่ Padding ด้วย 0 แล้วนะ มันกลายเป็น Padding ด้วย Space แทน ยิ่งเราเพิ่มเลขด้านหน้า มันก็ยิ่งห่างออกไป เรื่อย ๆ แล้วมันคืออะไรกัน จริง ๆ แล้วมันคือการกำหนด Column ละ เดี๋ยวเราลองดูตัวอย่างด้านล่าง

product_info = [{'id': 1 , 'price': 200, 'qty':5}, {'id': 2 , 'price': 500, 'qty':20}]

for product in product_info :
    print(f"{product['id']:03} {product['price']:13} {product['qty']:23}")
001           200                       5
002           500                      20

พอเราทำออกมาจริง ๆ จะเห็นได้ว่า มันจะช่วย Format ให้ข้อมูลของเอาออกมาเป็นตารางอย่างที่เราเห็นเลย มันทำให้เราสามารถแสดงข้อมูลได้อย่างง่ายดายเลยละ

สรุป

F-String จริง ๆ มันก็คือร่างทรงของ Format ที่เราใช้งานกันปกตินี่ละ แต่แค่ว่า เราใช้มันให้อยู่ในรูปของ Shorthand เท่านั้นเอง แต่พอเอามาใช้งานจริง ๆ มันทำให้ง่ายกว่าเดิมเยอะมาก ทั้งในแง่ของการเขียน และการ Maintain เอง ยิ่งกว่านั้น Feature นี้มัน Built-in มาใน Python เลย ทำให้เราไม่จำเป็นที่จะต้องมานั่งลง Library อะไรให้ยุ่งยากอีกด้วย แนะนำเลยอ่ะ ลองไปเล่นกันได้ จริง ๆ มันยังมี Format พิศดารอีกหลาย ๆ อย่างที่เราไม่ได้เอามาเล่าในบทความนี้

Read Next...

การสร้าง SSD Storage Pool บน Synology DSM

การสร้าง SSD Storage Pool บน Synology DSM

สำหรับคนที่ใช้ Synology NAS บางรุ่นจะมีช่อง M.2 สำหรับเสียบ NVMe SSD โดยพื้นฐาน Synology บอกว่ามันสำหรับการทำ Cache แต่ถ้าเราต้องการเอามันมาทำเป็น Storage ละ มันจะทำได้มั้ย วันนี้เราจะมาเล่าวิธีการทำกัน...

Multiprogramming, Multiprocessing และ Multithreading

Multiprogramming, Multiprocessing และ Multithreading

หลังจากที่เรามาเล่าเรื่อง malloc() มีคนอยากให้มาเล่าเรื่อง pthread เพื่อให้สามารถยัด Content ที่ละเอียด และเข้าใจง่ายในเวลาที่ไม่นานเกินไป เลยจะมาเล่าพื้นฐานที่สำคัญของคำ 3 คำคือ Multiprogramming, Multitasking, Multiprocessing และ Multithreading...

Synology NAS และ SSD Cache จำเป็นจริง ๆ เหรอ เหมาะกับระบบแบบใด

Synology NAS และ SSD Cache จำเป็นจริง ๆ เหรอ เหมาะกับระบบแบบใด

ใน Synology NAS มีความสามารถนึงที่น่าสนใจคือ การใช้ SSD เป็น Cache สำหรับระบบ ที่ทำให้ Performance ในการอ่านเขียน เร็วขึ้นกว่าเดิมมาก ๆ แน่นอนว่า เราลองละ วันนี้เราจะมาเล่าให้อ่านกันว่า หากใครคิดที่จะทำ มันเหมาะ หรือ ไม่เหมาะกับการใช้งานของเรา...

ฮาวทูย้าย Synology Add-on Package ไปอีก Volume

ฮาวทูย้าย Synology Add-on Package ไปอีก Volume

เรื่องราวเกิดจากการที่เราต้องย้าย Add-on Package ใน DSM และคิดว่าหลาย ๆ คนน่าจะต้องประสบเรื่องราวคล้าย ๆ กัน วันนี้เราจะมาเล่าวิธีการว่า เราทำยังไง เจอปัญหาอะไร และ แก้ปัญหาอย่างไรให้ได้อ่านกัน...