ข้ามไปยังเนื้อหาหลัก

ฟังก์ชันใน Python: วิธีเรียกใช้และเขียนฟังก์ชัน

ค้นพบวิธีเขียนฟังก์ชัน Python ที่นำกลับมาใช้ซ้ำและมีประสิทธิภาพ เชี่ยวชาญพารามิเตอร์ คำสั่ง return และหัวข้อขั้นสูงอย่างฟังก์ชันแลมบ์ดา จัดโค้ดให้เป็นระเบียบยิ่งขึ้นด้วย main() และแนวปฏิบัติที่ดีอื่น ๆ
· 14 นาที อ่าน

สำรวจด้วย AI

แบนเนอร์ทักษะ Python เพื่อสร้างอาชีพกับ DataCamp

ฟังก์ชันเป็นส่วนสำคัญของภาษาโปรแกรม Python: อาจเคยพบและใช้งานฟังก์ชันมากมายที่มีมาให้ในภาษา Python หรือที่มาพร้อมระบบนิเวศไลบรารี อย่างไรก็ตาม ในฐานะนักวิทยาศาสตร์ข้อมูล จะต้องเขียนฟังก์ชันของตนเองอยู่เสมอเพื่อแก้ปัญหาที่เกิดจากข้อมูลของคุณ 

บทช่วยสอนนี้ใช้ไวยากรณ์ Python 3 ตัวอย่างทั้งหมดทำงานบน Python 3.10+ และได้รับการอัปเดตให้สะท้อนแนวปฏิบัติสมัยใหม่แล้ว (f-strings, type hints, พารามิเตอร์แบบ positional-only และ keyword-only) เวอร์ชันเสถียรปัจจุบันคือ Python 3.14

หากต้องการรันโค้ดตัวอย่างทั้งหมดในบทช่วยสอนนี้ได้อย่างง่ายดาย สามารถสร้างสมุดงาน DataLab ได้ฟรี ที่ติดตั้ง Python ไว้ล่วงหน้าและมีโค้ดตัวอย่างทั้งหมด สำหรับการฝึกเขียนฟังก์ชัน Python เพิ่มเติม ลองดูแบบฝึกหัดเชิงปฏิบัติของ DataCamp นี้ หรือเรียนคอร์ส Python Data Science Toolbox!

ฟังก์ชันใน Python

ในการเขียนโปรแกรมจะใช้ฟังก์ชันเพื่อรวมชุดคำสั่งที่ต้องการใช้ซ้ำ หรือที่เนื่องจากความซับซ้อนแล้วควรแยกเป็นโปรแกรมย่อยและเรียกใช้เมื่อจำเป็น นั่นหมายความว่าฟังก์ชันคือส่วนของโค้ดที่เขียนขึ้นเพื่อทำงานตามที่ระบุไว้ เพื่อทำงานนั้น ฟังก์ชันอาจต้องการหรือไม่ต้องการอินพุตหลายตัวก็ได้ เมื่อทำงานเสร็จ ฟังก์ชันอาจคืนค่าหนึ่งค่าหรือหลายค่าก็ได้

ใน Python มีฟังก์ชันอยู่สามประเภท:

  • ฟังก์ชันที่มีมาให้แล้ว (Built-in) เช่น help() เพื่อขอความช่วยเหลือ, min() เพื่อหาค่าต่ำสุด, print() เพื่อพิมพ์วัตถุไปยังเทอร์มินัล เป็นต้น สามารถดูภาพรวมของฟังก์ชันเหล่านี้เพิ่มเติมได้ ที่นี่

  • ฟังก์ชันที่ผู้ใช้กำหนดเอง (User-Defined Functions: UDFs) คือฟังก์ชันที่ผู้ใช้สร้างขึ้นเพื่อช่วยงานของตน และ

  • ฟังก์ชันนิรนาม ซึ่งเรียกอีกอย่างว่าฟังก์ชันแลมบ์ดา เพราะไม่ได้ประกาศด้วยคีย์เวิร์ดมาตรฐาน def

ฟังก์ชัน vs เมธอด

เมธอดหมายถึงฟังก์ชันที่เป็นส่วนหนึ่งของคลาส ต้องเข้าถึงผ่านอินสแตนซ์หรืออ็อบเจ็กต์ของคลาส ฟังก์ชันไม่มีข้อจำกัดนี้: เป็นฟังก์ชันแบบสแตนด์อโลน นั่นหมายความว่าเมธอดทุกตัวเป็นฟังก์ชัน แต่ฟังก์ชันไม่ใช่เมธอดเสมอไป

พิจารณาตัวอย่างนี้ ที่กำหนดฟังก์ชัน plus() ก่อน จากนั้นกำหนดคลาส Summation พร้อมเมธอด sum():

# Define a function `plus()`
def plus(a,b):
  return a + b
  
# Create a `Summation` class
class Summation(object):
  def sum(self, a, b):
    self.contents = a + b
    return self.contents 

หากต้องการเรียกใช้เมธอด sum() ที่เป็นส่วนหนึ่งของคลาส Summation จะต้องนิยามอินสแตนซ์หรืออ็อบเจ็กต์ของคลาสนั้นก่อน มาสร้างอ็อบเจ็กต์ดังกล่าวกัน:

# Instantiate `Summation` class to call `sum()`
sumInstance = Summation()
sumInstance.sum(1,2)

จำไว้ว่าการสร้างอินสแตนซ์นี้ไม่จำเป็นเมื่อจะเรียกใช้ฟังก์ชัน plus() สามารถรัน plus(1,2) ในส่วนโค้ด DataCamp Light ได้โดยไม่มีปัญหา!

พารามิเตอร์ vs อาร์กิวเมนต์

พารามิเตอร์คือชื่อที่ใช้เมื่อกำหนดฟังก์ชันหรือเมธอด และจะถูกแมปกับอาร์กิวเมนต์ กล่าวอีกนัยหนึ่ง อาร์กิวเมนต์คือสิ่งที่ส่งให้กับการเรียกใช้ฟังก์ชันหรือเมธอด ขณะที่โค้ดของฟังก์ชันหรือเมธอดจะอ้างถึงอาร์กิวเมนต์เหล่านั้นด้วยชื่อพารามิเตอร์

พิจารณาตัวอย่างต่อไปนี้และย้อนกลับไปดูส่วน DataCamp Light ด้านบน: คุณส่งอาร์กิวเมนต์สองตัวไปยังเมธอด sum() ของคลาส Summation แม้ว่าก่อนหน้านี้จะกำหนดพารามิเตอร์ไว้สามตัว ได้แก่ self, a และ b

self หายไปไหน?

อาร์กิวเมนต์ตัวแรกของเมธอดในคลาสทุกตัวจะเป็นการอ้างอิงไปยังอินสแตนซ์ปัจจุบันของคลาส ซึ่งในที่นี้คือ Summation ตามธรรมเนียมจะเรียกอาร์กิวเมนต์นี้ว่า self

ทั้งหมดนี้หมายความว่าไม่ต้องส่งการอ้างอิงไปยัง self ในกรณีนี้ เพราะ self เป็นชื่อพารามิเตอร์สำหรับอาร์กิวเมนต์ที่ส่งโดยปริยาย ซึ่งอ้างถึงอินสแตนซ์ที่ใช้เรียกเมธอด มันจะถูกแทรกเข้าไปในรายการอาร์กิวเมนต์โดยอัตโนมัติ

วิธีนิยามฟังก์ชัน: ฟังก์ชันที่ผู้ใช้กำหนดเอง (UDFs)

สี่ขั้นตอนในการนิยามฟังก์ชันใน Python มีดังนี้:

  1. ใช้คีย์เวิร์ด def เพื่อประกาศฟังก์ชัน แล้วตามด้วยชื่อฟังก์ชัน

  2. เพิ่มพารามิเตอร์ให้กับฟังก์ชัน: ควรอยู่ในวงเล็บของฟังก์ชัน ลงท้ายบรรทัดด้วยโคลอน

  3. เพิ่มคำสั่งที่ฟังก์ชันควรดำเนินการ

  4. จบฟังก์ชันด้วยคำสั่ง return หากฟังก์ชันต้องการส่งผลลัพธ์ออกมา หากไม่มีคำสั่ง return ฟังก์ชันจะคืนค่าเป็นอ็อบเจ็กต์ None

def hello():
  print("Hello World") 
  return 

แน่นอนว่าเมื่อทำไป ฟังก์ชันจะซับซ้อนขึ้น: สามารถเพิ่ม for loop การควบคุมโฟลว์ ฯลฯ เพื่อให้ละเอียดขึ้นได้:

def hello():
    name = input("Enter your name: ")
    if name:
        print(f"Hello {name}")
    else:
        print("Hello World")

hello()

ในฟังก์ชันข้างต้น จะให้ผู้ใช้กรอกชื่อ หากไม่มีการกรอกชื่อ ฟังก์ชันจะพิมพ์ “Hello World” มิฉะนั้น ผู้ใช้จะได้รับคำทักทายแบบระบุชื่อ

โปรดจำไว้ด้วยว่าสามารถกำหนดพารามิเตอร์หนึ่งตัวหรือมากกว่าสำหรับ UDF ได้ จะได้เรียนรู้เพิ่มเติมเมื่อเข้าสู่หัวข้ออาร์กิวเมนต์ของฟังก์ชัน นอกจากนี้ ฟังก์ชันอาจคืนค่าหนึ่งค่าหรือหลายค่าก็ได้

คำสั่ง return

สังเกตว่าเนื่องจากพิมพ์บางอย่างใน UDF hello() อยู่แล้ว จึงไม่จำเป็นต้องคืนค่า จะไม่เห็นความแตกต่างระหว่างฟังก์ชันด้านบนกับฟังก์ชันนี้:

def hello_noreturn():
  print("Hello World") 

อย่างไรก็ตาม หากต้องการทำงานต่อกับผลลัพธ์ของฟังก์ชันและลองทำโอเปอเรชันกับมัน จะต้องใช้คำสั่ง return เพื่อคืนค่าจริง เช่น สตริง จำนวนเต็ม เป็นต้น พิจารณาสถานการณ์ต่อไปนี้ ซึ่ง hello() คืนค่าสตริง "hello" ในขณะที่ฟังก์ชัน hello_noreturn() คืนค่า None:

def hello():
  print("Hello World") 
  return("hello")

def hello_noreturn():
  print("Hello World")
  
# Multiply the output of `hello()` with 2 
hello() * 2

# (Try to) multiply the output of `hello_noreturn()` with 2 
hello_noreturn() * 2

ฟังก์ชันที่สองจะเกิดข้อผิดพลาดเพราะไม่สามารถทำโอเปอเรชันใด ๆ กับ None ได้ จะได้รับ TypeError ระบุว่าไม่สามารถทำการคูณระหว่าง NoneType (None ที่เป็นผลจาก hello_noreturn()) กับ int (2)

เคล็ดลับ ฟังก์ชันจะออกจากการทำงานทันทีเมื่อพบคำสั่ง return แม้ว่าจะไม่ได้คืนค่าใด ๆ ก็ตาม:

def run():
  for x in range(10):
     if x == 2:
       return
  print("Run!")
  
run()

อีกประเด็นที่ควรกล่าวถึงเมื่อทำงานกับคำสั่ง return คือสามารถใช้เพื่อคืนค่าหลายค่าได้ โดยทำผ่านทูเพิล

โปรดจำไว้ว่าโครงสร้างข้อมูลนี้คล้ายกับลิสต์มาก: สามารถมีหลายค่า แต่ทูเพิลเป็นแบบเปลี่ยนค่าไม่ได้ (immutable) หมายความว่าไม่สามารถแก้ไขค่าที่เก็บอยู่ได้ สร้างได้ด้วยวงเล็บคู่ () สามารถแตกทูเพิลไปยังตัวแปรหลายตัวได้ด้วยเครื่องหมายจุลภาคและโอเปอเรเตอร์กำหนดค่า

ดูตัวอย่างต่อไปนี้เพื่อทำความเข้าใจว่าฟังก์ชันของคุณสามารถคืนค่าหลายค่าได้อย่างไร:

# Define `plus()`
def plus(a,b):
  sum = a + b
  return (sum, a)

# Call `plus()` and unpack variables 
sum, a = plus(3,4)

# Print `sum()`
print(sum)

หมายเหตุ คำสั่ง return อย่าง return sum, a จะให้ผลเหมือนกับ return (sum, a): แบบแรกจริง ๆ แล้วแพ็ก sum และ a เข้าเป็นทูเพิลเบื้องหลัง!

วิธีเรียกใช้ฟังก์ชัน

ในส่วนก่อนหน้าได้เห็นตัวอย่างมากมายแล้วว่าการเรียกใช้ฟังก์ชันทำอย่างไร การเรียกใช้ฟังก์ชันหมายถึงการรันฟังก์ชันที่นิยามไว้ แล้วแต่จะเรียกตรงจากพรอมต์ Python หรือผ่านฟังก์ชันอื่น (ดังที่จะเห็นในหัวข้อ “Nested Functions”)

เรียกใช้ฟังก์ชัน hello() ที่นิยามใหม่ได้โดยรัน hello() เหมือนในส่วน DataCamp Light ด้านล่างนี้:

hello()

วิธีเพิ่ม docstring ให้ฟังก์ชัน Python

อีกแง่มุมสำคัญของการเขียนฟังก์ชันใน Python: docstring Docstring อธิบายว่าฟังก์ชันทำอะไร เช่น การคำนวณที่ทำหรือค่าที่คืนค่า คำอธิบายนี้ทำหน้าที่เป็นเอกสารของฟังก์ชัน เพื่อให้ผู้ใดก็ตามที่อ่าน docstring ของฟังก์ชันเข้าใจได้ว่าฟังก์ชันทำอะไร โดยไม่ต้องไล่ตามโค้ดทั้งหมดในคำนิยามฟังก์ชัน

Docstring ของฟังก์ชันจะวางไว้บรรทัดถัดจากส่วนหัวของฟังก์ชันและคั่นด้วยเครื่องหมายอัญประกาศสามตัว Docstring ที่เหมาะสมสำหรับฟังก์ชัน hello() คือ ‘พิมพ์ “Hello World”’

def hello() -> None:
    """Prints "Hello World"."""
    print("Hello World")

หมายเหตุ ว่า docstring อาจยาวกว่าตัวอย่างนี้ได้ หากต้องการศึกษา docstring โดยละเอียด แนะนำให้ดูที่คลัง GitHub ของไลบรารี Python เช่น scikit-learn หรือ pandas ซึ่งมีตัวอย่างมากมาย!

Type hints

สิ่งที่เกี่ยวข้องใกล้ชิดกับ docstring และพบเห็นได้บ่อยในโค้ด Python สมัยใหม่คือ type hint ตั้งแต่ Python 3.5 เป็นต้นมา สามารถใส่คำอธิบายชนิดข้อมูลให้กับพารามิเตอร์ของฟังก์ชันและค่าที่คืนว่าจะเป็นชนิดใด ตัวอย่างง่ายที่สุดมีดังนี้:

def plus(a: int, b: int) -> int:
    return a + b

เครื่องหมาย : int หลังแต่ละพารามิเตอร์หมายถึง “ควรเป็นจำนวนเต็ม” และ -> int หลังวงเล็บหมายถึง “ฟังก์ชันนี้คืนค่าเป็นจำนวนเต็ม” Python เองจะไม่บังคับใช้คำอธิบายนี้ขณะรันไทม์ ยังคงส่งสตริงเข้า plus() ได้และ Python จะไม่ร้องจนกว่าจะเกิดปัญหา แต่เครื่องมืออย่าง mypy, pyright และระบบตรวจชนิดในตัวของตัวแก้ไขอย่าง VS Code และ PyCharm จะใช้ hint เหล่านี้เพื่อจับบั๊กก่อนที่จะรันโค้ดจริง

สำหรับชนิดที่ซับซ้อนขึ้น สามารถใช้ generic ที่มีมาให้โดยตรง (ตั้งแต่ Python 3.9+) หรือ import จากโมดูล typing:

def greet(names: list[str]) -> None:
    for name in names:
        print(f"Hello {name}")

def find_user(user_id: int) -> dict | None:
    # returns the user dict, or None if not found
    ...
Type hint เป็นตัวเลือก แต่ถือเป็นแนวปฏิบัติที่ดีสำหรับฟังก์ชันที่ตั้งใจจะนำกลับมาใช้ซ้ำ แบ่งปัน หรือย้อนกลับมาดูในอีกหกเดือนข้างหน้า 它们ทำหน้าที่เป็นเอกสารที่เครื่องตรวจสอบได้ IDE จะเติมคำอัตโนมัติตามนั้น จับการพิมพ์ผิด และเตือนเมื่อส่งชนิดไม่ถูกต้อง

อาร์กิวเมนต์ของฟังก์ชันใน Python

ก่อนหน้านี้ได้เรียนรู้ความแตกต่างระหว่างพารามิเตอร์และอาร์กิวเมนต์โดยย่อแล้ว อาร์กิวเมนต์คือสิ่งที่ส่งให้กับการเรียกใช้ฟังก์ชันหรือเมธอด ขณะที่โค้ดของฟังก์ชันหรือเมธอดจะอ้างถึงอาร์กิวเมนต์ด้วยชื่อพารามิเตอร์ UDF ใน Python รองรับอาร์กิวเมนต์สี่ประเภท:

  • อาร์กิวเมนต์ค่าเริ่มต้น (Default arguments)
  • อาร์กิวเมนต์ที่จำเป็น (Required arguments)
  • อาร์กิวเมนต์แบบระบุคีย์เวิร์ด (Keyword arguments)
  • จำนวนอาร์กิวเมนต์แปรผัน (Variable number of arguments)

Default Arguments

อาร์กิวเมนต์ค่าเริ่มต้นคืออาร์กิวเมนต์ที่รับค่าเริ่มต้นหากไม่มีการส่งค่าเข้ามาระหว่างการเรียกใช้ฟังก์ชัน สามารถกำหนดค่าเริ่มต้นนี้ได้ด้วยโอเปอเรเตอร์กำหนดค่า = ดังตัวอย่างต่อไปนี้:

# Define `plus()` function
def plus(a,b = 2):
  return a + b
  
# Call `plus()` with only `a` parameter
plus(a=1)

# Call `plus()` with `a` and `b` parameters
plus(a=1, b=3)

Required Arguments

ตามชื่อ อาร์กิวเมนต์ที่จำเป็นของ UDF คือสิ่งที่ต้องมี อาร์กิวเมนต์เหล่านี้ต้องถูกส่งเข้ามาระหว่างการเรียกใช้ฟังก์ชันและต้องอยู่ในลำดับที่ถูกต้อง ดังตัวอย่างต่อไปนี้:

# Define `plus()` with required arguments
def plus(a,b):
  return a + b

จำเป็นต้องมีอาร์กิวเมนต์ที่แมปกับพารามิเตอร์ a และ b เพื่อเรียกใช้ฟังก์ชันโดยไม่เกิดข้อผิดพลาด หากสลับ a และ b ผลลัพธ์จะไม่ต่างกัน แต่จะต่างกันได้หากเปลี่ยน plus() เป็นแบบต่อไปนี้:

# Define `plus()` with required arguments
def plus(a,b):
  return a/b

Keyword Arguments

หากต้องการให้แน่ใจว่าเรียกพารามิเตอร์ถูกลำดับ สามารถใช้อาร์กิวเมนต์แบบคีย์เวิร์ดในการเรียกฟังก์ชัน ใช้วิธีนี้เพื่อระบุอาร์กิวเมนต์ด้วยชื่อพารามิเตอร์ มาดูตัวอย่างจากด้านบนเพื่อให้ชัดเจนขึ้น:

# Define `plus()` function
def plus(a,b):
  return a + b
  
# Call `plus()` function with parameters 
plus(2,3)

# Call `plus()` function with keyword arguments
plus(a=1, b=2)

สังเกตว่าเมื่อใช้อาร์กิวเมนต์แบบคีย์เวิร์ด สามารถสลับลำดับพารามิเตอร์และยังคงได้ผลลัพธ์เดียวกันเมื่อรันฟังก์ชัน:

# Define `plus()` function
def plus(a,b):
  return a + b
  
# Call `plus()` function with keyword arguments
plus(b=2, a=1)

จำนวนอาร์กิวเมนต์แปรผัน

ในกรณีที่ไม่ทราบจำนวนอาร์กิวเมนต์ที่ต้องการส่งให้ฟังก์ชันแน่ชัด สามารถใช้ไวยากรณ์ดังต่อไปนี้กับ *args ได้:

# Define `plus()` function to accept a variable number of arguments
def plus(*args):
  return sum(args)

# Calculate the sum
plus(1,4,5)

เครื่องหมายดอกจัน (*) วางไว้หน้าชื่อตัวแปรที่เก็บค่าของอาร์กิวเมนต์แบบไม่ใช่คีย์เวิร์ดทั้งหมด สังเกตว่าสามารถใช้ชื่ออื่นแทน *args เช่น *varint, *var_int_args หรือชื่อใด ๆ เมื่อส่งเข้าไปยังฟังก์ชัน plus() ก็ได้

เคล็ดลับ: ลองแทนที่ *args ด้วยชื่ออื่นที่มีดอกจัน จะเห็นว่าโค้ดด้านบนยังทำงานต่อไปได้!

จะเห็นว่าฟังก์ชันด้านบนใช้ฟังก์ชันที่มีมาให้ของ Python อย่าง sum() เพื่อบวกรวมอาร์กิวเมนต์ทั้งหมดที่ส่งเข้าไปยัง plus() 

ตัวแปรแบบ global กับแบบ local

โดยทั่วไป ตัวแปรที่กำหนดในเนื้อฟังก์ชันจะมีขอบเขตแบบ local ส่วนตัวแปรที่กำหนดไว้ภายนอกจะมีขอบเขตแบบ global นั่นหมายความว่า ตัวแปร local ถูกกำหนดภายในบล็อกของฟังก์ชันและเข้าถึงได้เฉพาะภายในฟังก์ชันนั้น ขณะที่ตัวแปร global สามารถเข้าถึงได้โดยฟังก์ชันทั้งหมดในสคริปต์ของคุณ:

จะเห็นว่าเกิด NameError ระบุว่า name 'total' is not defined เมื่อพยายามพิมพ์ตัวแปร local total ที่ถูกกำหนดภายในเนื้อฟังก์ชัน ด้านทางกลับกัน ตัวแปร init สามารถพิมพ์ได้โดยไม่มีปัญหา

พารามิเตอร์แบบ positional-only และ keyword-only

ตั้งแต่ Python 3.8 เป็นต้นมา สามารถควบคุมวิธีการส่งอาร์กิวเมนต์ได้มากขึ้นด้วยเครื่องหมายพิเศษสองตัวในลายเซ็นของฟังก์ชัน คือ / และ * สิ่งที่อยู่ก่อน / จะส่งได้เฉพาะแบบตำแหน่งเท่านั้น ส่วนที่อยู่หลัง * จะส่งได้เฉพาะแบบคีย์เวิร์ดเท่านั้น

def greet(name, /, greeting="Hello", *, punctuation="!"):
    print(f"{greeting} {name}{punctuation}")

 ตัวอย่างการเรียกใช้จะเป็นดังนี้:

greet("Alice")                          # works
greet("Alice", greeting="Hi")           # works
greet("Alice", "Hi", punctuation="?")   # works

greet(name="Alice")                     # TypeError: name is positional-only
greet("Alice", "Hi", "?")               # TypeError: punctuation is keyword-only

ทำไมถึงอยากใช้แบบนี้? มีสองเหตุผลหลัก

หนึ่ง, พารามิเตอร์แบบ positional-only ช่วยให้เปลี่ยนชื่อในภายหลังได้โดยไม่ทำให้โค้ดของใครพัง เพราะไม่มีใครได้รับอนุญาตให้ใช้ชื่อนั้นเป็นคีย์เวิร์ด จึงเปลี่ยนชื่อได้อิสระ

สอง, พารามิเตอร์แบบ keyword-only บังคับให้ผู้เรียกใช้ระบุอย่างชัดเจนว่ากำลังส่งอะไร ทำให้การเรียกอ่านง่ายขึ้นเมื่อมีแฟลกหรือการตั้งค่าทางเลือกหลายตัว

สรุปคือ เป็นวิธีที่สะอาดในการบังคับใช้เจตนา

ฟังก์ชันนิรนามใน Python

ฟังก์ชันนิรนามใน Python เรียกว่าฟังก์ชันแลมบ์ดา เพราะแทนที่จะประกาศด้วยคีย์เวิร์ดมาตรฐาน def จะใช้คีย์เวิร์ด lambda

double = lambda x: x*2

double(5)

ในส่วน DataCamp Light ด้านบน lambda x: x*2 คือฟังก์ชันนิรนามหรือฟังก์ชันแลมบ์ดา x คืออาร์กิวเมนต์ และ x*2 คือ expression หรือคำสั่งที่ถูกประเมินและคืนค่า ความพิเศษของฟังก์ชันนี้คือไม่มีชื่อ แตกต่างจากตัวอย่างในส่วนแรกของบทช่วยสอนฟังก์ชัน หากต้องเขียนฟังก์ชันข้างต้นเป็น UDF จะได้ผลลัพธ์ดังนี้:

def double(x):
  return x*2

พิจารณาตัวอย่างฟังก์ชันแลมบ์ดาที่ทำงานกับอาร์กิวเมนต์สองตัว:

# `sum()` lambda function
sum = lambda x, y: x + y;

# Call the `sum()` anonymous function
sum(4,5)

# "Translate" to a UDF
def sum(x, y):
  return x+y

มักใช้ฟังก์ชันนิรนามเมื่อจำเป็นต้องใช้ฟังก์ชันที่ไม่มีชื่อชั่วคราวและถูกสร้างขึ้นขณะรันไทม์ บริบทที่เกี่ยวข้องเช่นเมื่อทำงานกับ filter(), map() และ reduce():

from functools import reduce

my_list = [1,2,3,4,5,6,7,8,9,10]

# Use lambda function with `filter()`
filtered_list = list(filter(lambda x: (x*2 > 10), my_list))

# Use lambda function with `map()`
mapped_list = list(map(lambda x: x*2, my_list))

# Use lambda function with `reduce()`
reduced_list = reduce(lambda x, y: x+y, my_list)

print(filtered_list)
print(mapped_list)
print(reduced_list)

ฟังก์ชัน filter() จะกรองลิสต์อินพุตเดิม my_list ตามเงื่อนไข >10 ตามชื่อของมัน ส่วน map() จะนำฟังก์ชันไปใช้กับทุกองค์ประกอบของลิสต์ my_list ในที่นี้คือคูณทุกองค์ประกอบด้วย 2

สังเกตว่า reduce() อยู่ในไลบรารี functools ใช้ฟังก์ชันนี้แบบสะสมกับรายการในลิสต์ my_list จากซ้ายไปขวา และย่อลำดับให้เหลือค่าเดียว ซึ่งในที่นี้คือ 55

การใช้ main() เป็นฟังก์ชันใน Python

หากมีประสบการณ์กับภาษาอื่นอย่าง Java จะทราบว่าต้องมีฟังก์ชัน main เพื่อรันฟังก์ชันต่าง ๆ แต่จากตัวอย่างด้านบนจะเห็นว่า Python ไม่จำเป็นต้องมี อย่างไรก็ตาม การใส่ฟังก์ชัน main() ในโปรแกรม Python จะช่วยจัดโครงร่างโค้ดอย่างมีเหตุผล องค์ประกอบที่สำคัญที่สุดจะถูกรวมไว้ในฟังก์ชัน main() นี้

สามารถนิยามฟังก์ชัน main() และเรียกใช้ได้ง่าย ๆ เช่นเดียวกับฟังก์ชันอื่น ๆ ด้านบน:

# Define `main()` function
def main():
  hello()
  print("This is a main function")

main()

อย่างไรก็ตาม ในสภาพนี้ โค้ดของฟังก์ชัน main() จะถูกเรียกเมื่อมีการ import ไฟล์เป็นโมดูล เพื่อป้องกันไม่ให้เกิดขึ้น ควรเรียกฟังก์ชัน main() เมื่อ __name__ == '__main__'

ดังนั้นโค้ดในส่วนด้านบนจะกลายเป็นดังนี้:

# Define `main()` function
def main():
  hello()
  print("This is a main function")
  
# Execute `main()` function 
if __name__ == '__main__':
    main()

หมายเหตุ นอกเหนือจากฟังก์ชัน __main__ แล้ว ยังมีฟังก์ชัน __init__ ที่ใช้เริ่มต้นอินสแตนซ์ของคลาสหรืออ็อบเจ็กต์ กล่าวโดยย่อคือทำหน้าที่เป็นคอนสตรักเตอร์หรือตัวเริ่มต้น และถูกเรียกอัตโนมัติเมื่อสร้างอินสแตนซ์ของคลาสใหม่ ด้วยฟังก์ชันนี้ อ็อบเจ็กต์ที่สร้างใหม่จะถูกกำหนดให้กับพารามิเตอร์ self ซึ่งเห็นไปแล้วในบทช่วยสอนนี้ ดูตัวอย่างต่อไปนี้:

class Dog:
    """A simple Dog class.

    Args:
        legs: Number of legs so that the dog can walk.
        color: The color of the fur.
    """

    def __init__(self, legs: int, color: str) -> None:
        self.legs = legs
        self.color = color

    def bark(self) -> str:
        return "bark" * 2

if __name__ == "__main__":
    dog = Dog(4, "brown")
    print(dog.bark())

ฝึกฟังก์ชัน Python ต่อให้คล่อง

ยินดีด้วย! ผ่านบทช่วยสั้น ๆ เกี่ยวกับฟังก์ชันใน Python แล้ว หากต้องการทบทวนเนื้อหา Python พื้นฐานอื่น ๆ อย่าพลาดคอร์ส Data Types for Data Science ซึ่งจะช่วยย้ำและฝึกความรู้เกี่ยวกับลิสต์, ดิกชันนารี, ทูเพิล, เซต และวันที่และเวลา

คำถามที่พบบ่อยเกี่ยวกับฟังก์ชันใน Python

ฟังก์ชันใน Python คืออะไร?

ฟังก์ชันคือบล็อกโค้ดที่นำกลับมาใช้ซ้ำได้เพื่อทำงานเฉพาะอย่าง สามารถรับอินพุต ประมวลผล และคืนเอาต์พุตได้

กำหนดฟังก์ชันใน Python อย่างไร?

เพื่อกำหนดฟังก์ชันใน Python ให้ใช้คีย์เวิร์ด def ตั้งชื่อฟังก์ชัน ใส่พารามิเตอร์ (ถ้ามี) ในวงเล็บ เขียนโค้ด แล้วอาจใช้ return เพื่อคืนค่า

ความแตกต่างระหว่างฟังก์ชันกับเมธอดใน Python คืออะไร?

ฟังก์ชันอยู่เดี่ยว ๆ แต่เมธอดเป็นส่วนหนึ่งของคลาส เมธอดทั้งหมดคือฟังก์ชัน แต่ไม่ใช่ทุกฟังก์ชันคือเมธอด

ประเภทของฟังก์ชันใน Python มีอะไรบ้าง?

Python มีฟังก์ชันที่มีมาให้ (เช่น print()) ฟังก์ชันที่ผู้ใช้กำหนดเอง (ที่คุณสร้างขึ้น) และฟังก์ชันนิรนาม (ฟังก์ชัน lambda ชั่วคราว)

ความแตกต่างระหว่างพารามิเตอร์และอาร์กิวเมนต์คืออะไร?

พารามิเตอร์คือช่องว่างรองรับในคำจำกัดความของฟังก์ชัน ส่วนอาร์กิวเมนต์คือค่าจริงที่ส่งเข้าไปเมื่อเรียกใช้ฟังก์ชัน

ฟังก์ชันแลมบ์ดาคืออะไร?

ฟังก์ชันแลมบ์ดาคือฟังก์ชันไม่มีชื่อแบบบรรทัดเดียวสำหรับงานรวดเร็ว

ทำไมต้องใช้ฟังก์ชัน __main__?

ฟังก์ชัน __main__ ช่วยจัดโค้ดให้เป็นระเบียบและทำให้ส่วนที่ระบุรันเฉพาะเมื่อสคริปต์ถูกรันโดยตรง ไม่ใช่เมื่อถูก import

ความแตกต่างระหว่างตัวแปร global และ local คืออะไร?

ตัวแปรแบบ global ใช้ได้ทุกที่ ส่วนตัวแปรแบบ local ใช้ได้เฉพาะภายในฟังก์ชันของมันเท่านั้น

หัวข้อ