สมมติว่าฉันเขียนมัณฑนากรที่ทำอะไรธรรมดา ๆ ตัวอย่างเช่นอาจแปลงอาร์กิวเมนต์ทั้งหมดเป็นประเภทเฉพาะดำเนินการบันทึกใช้การบันทึก ฯลฯ
นี่คือตัวอย่าง:
def args_as_ints(f):
def g(*args, **kwargs):
args = [int(x) for x in args]
kwargs = dict((k, int(v)) for k, v in kwargs.items())
return f(*args, **kwargs)
return g
@args_as_ints
def funny_function(x, y, z=3):
"""Computes x*y + 2*z"""
return x*y + 2*z
>>> funny_function("3", 4.0, z="5")
22
ทุกอย่างดีจนถึงตอนนี้ อย่างไรก็ตามมีปัญหาอย่างหนึ่ง ฟังก์ชั่นตกแต่งไม่ได้เก็บเอกสารของฟังก์ชันดั้งเดิมไว้:
>>> help(funny_function)
Help on function g in module __main__:
g(*args, **kwargs)
โชคดีที่มีวิธีแก้ปัญหา:
def args_as_ints(f):
def g(*args, **kwargs):
args = [int(x) for x in args]
kwargs = dict((k, int(v)) for k, v in kwargs.items())
return f(*args, **kwargs)
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
@args_as_ints
def funny_function(x, y, z=3):
"""Computes x*y + 2*z"""
return x*y + 2*z
คราวนี้ชื่อฟังก์ชันและเอกสารประกอบถูกต้อง:
>>> help(funny_function)
Help on function funny_function in module __main__:
funny_function(*args, **kwargs)
Computes x*y + 2*z
แต่ยังมีปัญหาอยู่: ลายเซ็นฟังก์ชันผิด ข้อมูล "* args, ** kwargs" นั้นไร้ประโยชน์
จะทำอย่างไร? ฉันนึกถึงวิธีแก้ปัญหาง่ายๆ แต่มีข้อบกพร่องสองวิธี:
1 - รวมลายเซ็นที่ถูกต้องใน docstring:
def funny_function(x, y, z=3):
"""funny_function(x, y, z=3) -- computes x*y + 2*z"""
return x*y + 2*z
สิ่งนี้ไม่ดีเนื่องจากการทำซ้ำ ลายเซ็นจะยังแสดงไม่ถูกต้องในเอกสารที่สร้างขึ้นโดยอัตโนมัติ ง่ายต่อการอัปเดตฟังก์ชันและลืมเกี่ยวกับการเปลี่ยน docstring หรือพิมพ์ผิด [ และใช่ฉันตระหนักดีว่า docstring ซ้ำซ้อนกับเนื้อความของฟังก์ชันแล้ว โปรดเพิกเฉยต่อสิ่งนี้ funny_function เป็นเพียงตัวอย่างแบบสุ่ม ]
2 - ไม่ใช้มัณฑนากรหรือใช้มัณฑนากรแบบพิเศษสำหรับลายเซ็นเฉพาะทุกรายการ:
def funny_functions_decorator(f):
def g(x, y, z=3):
return f(int(x), int(y), z=int(z))
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
วิธีนี้ใช้ได้ดีกับชุดฟังก์ชันที่มีลายเซ็นเหมือนกัน แต่โดยทั่วไปแล้วไม่มีประโยชน์ ดังที่ได้กล่าวไปแล้วในตอนต้นว่าฉันต้องการใช้มัณฑนากรแบบทั่วไปทั้งหมด
ฉันกำลังมองหาวิธีแก้ปัญหาที่เป็นแบบทั่วไปและอัตโนมัติ
คำถามคือ: มีวิธีแก้ไขลายเซ็นฟังก์ชันตกแต่งหลังจากสร้างแล้วหรือไม่?
มิฉะนั้นฉันสามารถเขียนมัณฑนากรที่แยกลายเซ็นฟังก์ชันและใช้ข้อมูลนั้นแทน "* kwargs, ** kwargs" เมื่อสร้างฟังก์ชันตกแต่งได้หรือไม่ ฉันจะดึงข้อมูลนั้นได้อย่างไร ฉันจะสร้างฟังก์ชันตกแต่ง - กับผู้บริหารได้อย่างไร?
แนวทางอื่น ๆ หรือไม่?
inspect.Signature
เพิ่มในการจัดการกับฟังก์ชันตกแต่ง