เกี่ยวกับการพิมพ์เป็ด :
การพิมพ์เป็ดนั้นได้รับความช่วยเหลือจากการไม่ได้ทดสอบประเภทของข้อโต้แย้งในวิธีการและร่างกายโดยอาศัยเอกสารประกอบรหัสที่ชัดเจนและการทดสอบเพื่อให้แน่ใจว่าการใช้งานถูกต้อง
เกี่ยวกับการตรวจสอบข้อโต้แย้ง (EAFP: ง่ายกว่าที่จะขอการอภัยมากกว่าการอนุญาต) ตัวอย่างที่ดัดแปลงจากที่นี่ :
... มันเป็นสิ่งที่ต้องทำยิ่งกว่า:
def my_method(self, key):
try:
value = self.a_dict[member]
except TypeError:
# do something else
ซึ่งหมายความว่าทุกคนที่ใช้รหัสของคุณไม่จำเป็นต้องใช้พจนานุกรมจริงหรือคลาสย่อย - พวกเขาสามารถใช้วัตถุใด ๆ ที่ใช้อินเทอร์เฟซการแมป
น่าเสียดายในทางปฏิบัติมันไม่ง่ายอย่างนั้น ถ้าสมาชิกในตัวอย่างด้านบนอาจเป็นจำนวนเต็ม จำนวนเต็มไม่เปลี่ยนรูปดังนั้นจึงเหมาะสมอย่างยิ่งที่จะใช้เป็นคีย์พจนานุกรม อย่างไรก็ตามพวกมันยังใช้เพื่อจัดทำดัชนีวัตถุประเภทลำดับ หากสมาชิกเกิดขึ้นเป็นจำนวนเต็มตัวอย่างที่สองสามารถผ่านรายการและสตริงเช่นเดียวกับพจนานุกรม
เกี่ยวกับการเขียนโปรแกรมที่แน่วแน่ :
การยืนยันเป็นวิธีที่เป็นระบบในการตรวจสอบว่าสถานะภายในของโปรแกรมเป็นไปตามที่โปรแกรมเมอร์คาดไว้โดยมีเป้าหมายในการจับข้อบกพร่อง โดยเฉพาะอย่างยิ่งพวกเขาดีสำหรับการจับสมมติฐานที่ผิดพลาดที่เกิดขึ้นในขณะที่เขียนรหัสหรือใช้อินเทอร์เฟซโดยโปรแกรมเมอร์อื่น นอกจากนี้พวกเขาสามารถทำหน้าที่เป็นเอกสารในบรรทัดบางส่วนโดยทำให้สมมติฐานของโปรแกรมเมอร์ชัดเจน ("ชัดเจนดีกว่าโดยนัย")
แนวคิดที่กล่าวถึงบางครั้งมีข้อขัดแย้งดังนั้นฉันจึงพิจารณาปัจจัยต่อไปนี้เมื่อเลือกว่าฉันไม่ได้ทำการตรวจสอบความถูกต้องของข้อมูลเลยให้ทำการตรวจสอบความถูกต้องอย่างแรงหรือใช้การยืนยัน:
การตรวจสอบที่แข็งแกร่ง โดยการตรวจสอบที่แข็งแกร่งฉันหมายถึงการเพิ่มข้อยกเว้นที่กำหนดเอง (
ApiError
ตัวอย่าง) หากฟังก์ชัน / เมธอดของฉันเป็นส่วนหนึ่งของ API สาธารณะจะเป็นการดีกว่าถ้าตรวจสอบอาร์กิวเมนต์เพื่อแสดงข้อความแสดงข้อผิดพลาดที่ดีเกี่ยวกับประเภทที่ไม่คาดคิด โดยการตรวจสอบประเภทที่ฉันไม่ได้หมายถึงการใช้เพียงอย่างเดียวisinstance
แต่ยังถ้าวัตถุผ่านการสนับสนุนอินเทอร์เฟซที่จำเป็น (พิมพ์เป็ด) ในขณะที่ฉันทำเอกสาร API และระบุประเภทที่คาดหวังและผู้ใช้อาจต้องการใช้ฟังก์ชั่นของฉันในทางที่ไม่คาดคิดฉันรู้สึกปลอดภัยยิ่งขึ้นเมื่อฉันตรวจสอบสมมติฐาน ฉันมักจะใช้isinstance
และหากภายหลังฉันต้องการสนับสนุนเป็ดหรือเป็ดชนิดอื่นฉันจะเปลี่ยนตรรกะการตรวจสอบการเขียนโปรแกรมที่แน่วแน่ ถ้ารหัสของฉันใหม่ฉันใช้ยืนยันมาก คุณมีคำแนะนำอะไรเกี่ยวกับเรื่องนี้? คุณลบข้อความยืนยันออกจากรหัสในภายหลังหรือไม่
หากฟังก์ชัน / เมธอดของฉันไม่ได้เป็นส่วนหนึ่งของ API แต่ส่งผ่านข้อโต้แย้งบางอย่างไปยังโค้ดอื่นที่ไม่ได้เขียนศึกษาหรือทดสอบโดยฉันฉันจะทำการยืนยันจำนวนมากตามอินเตอร์เฟสที่เรียกใช้ ตรรกะของฉันที่อยู่เบื้องหลังสิ่งนี้ - ล้มเหลวในโค้ดของฉันได้ดีขึ้นจากนั้นอีก 10 ระดับที่ลึกลงไปในสแต็คเทรซที่มีข้อผิดพลาดที่เข้าใจยากซึ่งบังคับให้ดีบั๊กมากและต่อมา
ความคิดเห็นและคำแนะนำเกี่ยวกับเวลาที่จะใช้หรือไม่ใช้การตรวจสอบประเภท / ค่ายืนยันหรือไม่ ขออภัยที่ไม่ใช่คำถามที่ดีที่สุด
ตัวอย่างเช่นพิจารณาฟังก์ชันต่อไปนี้โดยที่Customer
เป็นรูปแบบการประกาศ SQLAlchemy:
def add_customer(self, customer):
"""Save new customer into the database.
@param customer: Customer instance, whose id is None
@return: merged into global session customer
"""
# no validation here at all
# let's hope SQLAlchemy session will break if `customer` is not a model instance
customer = self.session.add(customer)
self.session.commit()
return customer
ดังนั้นมีหลายวิธีในการจัดการการตรวจสอบ:
def add_customer(self, customer):
# this is an API method, so let's validate the input
if not isinstance(customer, Customer):
raise ApiError('Invalid type')
if customer.id is not None:
raise ApiError('id should be None')
customer = self.session.add(customer)
self.session.commit()
return customer
หรือ
def add_customer(self, customer):
# this is an internal method, but i want to be sure
# that it's a customer model instance
assert isinstance(customer, Customer), 'Achtung!'
assert customer.id is None
customer = self.session.add(customer)
self.session.commit()
return customer
คุณจะใช้สิ่งเหล่านี้ในบริบทของการพิมพ์เป็ดเมื่อใดและเพราะเหตุใดการตรวจสอบประเภทการตรวจสอบความถูกต้องของข้อมูล