วันพฤหัสบดีที่ 7 พฤษภาคม พ.ศ. 2552

python multi decorator

เนื่องจากเมื่อครั้งก่อนหน้านี้ ได้สร้าง decorator ในหัวข้อ python decorator แล้วบังเอิญว่า ไม่ได้ใช้ พอมาจับอีกทีถึงรู้ว่า คราวที่แล้ว ที่กำหนด decorator เป็น class นั้น มัีนค่อยข้างบีบความสามารถ ไว้ถ้าว่าง ๆ คงไปนั่งแก้และหาวิธีแก้ไขเพิม เนื่องเติมจาก ช่วงนี้ มีการเขียน code ที่ต้องเกี่ยวข้องกับระบบอื่น ๆ มากมาย หรือเรียกว่า ในส่วนที่ทำเป็น adaptor ก็ถูก

เอาเป็นว่าเข้าเรื่องดีกว่า ไม่รู้โม้ทำไม

เรื่องมีอยู่ว่า เนื่องจากในส่วนของ decorator ของ python นั้น มันค่อนข้างจะนำมาประยุกต์ใช้งาน ทำให้ code ที่ต้องเขียนซ้ำ ๆ กันน้อยลง นั่นคือ การใช้ @(decorator) ในการครอบ function บาง function โดยไม่ต้องเขียนให้เห็น ๆ กะตา

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

เริ่มเลย ...

decorator แรกนี้เป็นในส่วนทำการแสดงผล หลังจากทำงานเสร็จ เพื่อให้อยู่ใน format
def get_result(f):
    def wrap_func(*arg, **kw):
        try:
            f(*arg, **kw)
            return {'status_code':'200', 'status_description':'Success'}
        except Exception, e:
            return {'status_code':'500', 'status_description':str(e)}
    return wrap_func
ส่วนที่สอง เป็นในส่วน check parameter
def req_param(*fields):
    def req_paramn(f):
        def wrap_func(*arg, **kw):
            for field in fields:
                if not kw.has_key(field) or '' == kw.get(field).strip():
                    raise Exception('parameter %s not empty.' % field)
            return f(*arg, **kw)
        return wrap_func
    return req_paramn
ส่วนสุดท้าย function ที่ทำงาน
@sendcont_result
@req_param('ntype', 'to', 'from', 'message')
def on_call(**kw):
    try:
        if 'DTAC' == kw.get('ntype'):
            on_dtac(**kw)
        elif 'AIS' == kw.get('ntype'):
            on_ais(**kw)
        else:
            raise Exception('not support ntype %s.' % str(kw.get('ntype')))
        return kw
    except Exception, e:
        raise e
เวลาเรียกใช้ก็
res = on_call({'ntype':'AIS', 'message':'hi python.', 'to':'you', 'from','i'})
ผลลัพท์ 'res' ถ้าไม่เกิด error เราก็จะเป็น
status_code = 200
นอกนั้น ก็
status_code = 500

เช่น ในกรณีที่เราไม่ได้ใส่ ntype เข้ามา ก็จะฟ้องว่า
status_code = 500
status_description = parameter ntype not empty.
หรือ กรณี method on_dtac หรือ on_ais มีปัญหา ก็จะแสดงคล้ายข้างบนครับ

ตัวอย่างเท่านี้ ที่เหลือก็ขึ้นอยู่กับการประยุกต์ครับ

ไม่มีความคิดเห็น: