ทำความเข้าใจกับ Python Decorators

Python decorators เป็น feature หนึ่งของภาษา Python ซึ่ง feature นี้ไม่ใช่ Decorator pattern นะครับ เพียงแต่ว่าสามารถนำไปใช้ทำ pattern แบบนั้นได้

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

สมมุติว่าเรามีฟังก์ชั่น fizzbuzz ตามนี้

def fizzbuzz(number):
    if number % 3 == 0 and number % 5 == 0:
        return 'fizzbuzz'
    elif number % 3 == 0:
        return 'fizz'
    elif number % 5 == 0:
        return 'buzz'
    else:
        return number

แล้วเราอยากจะให้แสดงผลออกมาแบบมีข้อความขึ้นสักหน่อยเช่น Your input is 3, so you get fizz. ถ้าเราสะดวกเราก็เข้าไปแก้ฟังก์ชั่นของเราเลยใช่ไหมครับ เราก็จะได้ฟังก์ชั่นหน้าตาแบบนี้

def fizzbuzz(number):
    result = 'Your input is ' + str(number) + ', so you get '
    if number % 3 == 0 and number % 5 == 0:
        result += 'fizzbuzz'
    elif number % 3 == 0:
        result += 'fizz'
    elif number % 5 == 0:
        result += 'buzz'
    else:
        result += str(number)
    return result + '.'

ดูแล้วไม่ค่อยน่าทำเลยใช่ไหมครับ? เรามาลองใช้ decorator กันดีกว่า ให้เราสร้าง nested function หรือ inner function  ขึ้นมาตามนี้ (ที่ต้องทำตามนี้เพราะว่านี่เป็น syntax ของ Python decorator ครับ)

def have_nice_message(func):
    def wrap(number):
        result = 'Your input is ' + str(number) + ', so you get '
        result += func(number)
        result += '.'
        return result
    return wrap

วิธีใช้งานเราก็แค่เอาไปแปะไว้บนหัวของฟังก์ชั่นที่เราต้องการตามนี้

@have_nice_message
def fizzbuzz(number):
    if number % 3 == 0 and number % 5 == 0:
        return 'fizzbuzz'
    elif number % 3 == 0:
        return 'fizz'
    elif number % 5 == 0:
        return 'buzz'
    else:
        return number

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

Author: zkan

Soon to be a newbie data scientist. I ♥ machine learning, computer vision, robotics, image processing, data visualization, and data analytics.

Leave a Reply

Your email address will not be published. Required fields are marked *