คุณจะตรวจสอบว่าตัวแปรเป็นพจนานุกรมใน Python หรือไม่?
นี่เป็นคำถามที่ดี แต่มันเป็นโชคร้ายที่ upvoted type(obj) is dict
ที่สุดนำไปสู่คำตอบที่มีคำแนะนำที่น่าสงสาร
(โปรดทราบว่าคุณไม่ควรใช้dict
เป็นชื่อตัวแปร - เป็นชื่อของวัตถุบิวด์อิน)
หากคุณกำลังเขียนโค้ดที่ผู้อื่นจะนำเข้าและใช้งานอย่าสันนิษฐานว่าพวกเขาจะใช้ dict ในตัวโดยตรงทำให้ข้อสันนิษฐานนั้นทำให้โค้ดของคุณยืดหยุ่นมากขึ้นและในกรณีนี้ให้สร้างข้อบกพร่องที่ซ่อนได้ง่ายซึ่งไม่ผิดพลาดโปรแกรม .
ฉันขอแนะนำอย่างยิ่งสำหรับวัตถุประสงค์ของความถูกต้องความสามารถในการบำรุงรักษาและความยืดหยุ่นสำหรับผู้ใช้ในอนาคตไม่ควรมีความยืดหยุ่นน้อยกว่าและไม่มีการแสดงออกในรหัสของคุณเมื่อมีความยืดหยุ่นมากกว่า
is
เป็นการทดสอบเอกลักษณ์ของวัตถุตัวตนของวัตถุมันไม่สนับสนุนการสืบทอดมันไม่สนับสนุนสิ่งที่เป็นนามธรรมและไม่สนับสนุนอินเทอร์เฟซ
ดังนั้นฉันจะให้ตัวเลือกมากมายที่ทำ
สนับสนุนการสืบทอด:
นี่คือคำแนะนำแรกที่ผมจะทำเพราะจะช่วยให้ผู้ใช้สามารถจัดหา subclass ของตัวเองของ Dict หรือOrderedDict
, defaultdict
หรือCounter
จากคอลเลกชัน Module:
if isinstance(any_object, dict):
แต่มีตัวเลือกที่ยืดหยุ่นมากกว่า
รองรับ abstractions:
from collections.abc import Mapping
if isinstance(any_object, Mapping):
วิธีนี้ช่วยให้ผู้ใช้รหัสของคุณสามารถใช้การแมปแบบนามธรรมที่กำหนดเองซึ่งรวมถึงคลาสย่อยของ dict
และยังคงได้รับพฤติกรรมที่ถูกต้อง
ใช้ส่วนต่อประสาน
คุณมักได้ยินคำแนะนำ OOP "โปรแกรมไปยังส่วนต่อประสาน"
กลยุทธ์นี้ใช้ประโยชน์จากความหลากหลายของงูหลามหรือการพิมพ์เป็ด
ดังนั้นเพียงแค่พยายามที่จะเข้าถึงอินเตอร์เฟซจับข้อผิดพลาดเฉพาะที่คาดหวัง ( AttributeError
ในกรณีที่ไม่มี.items
และTypeError
ในกรณีที่items
ไม่ได้เป็น callable) มีทางเลือกที่เหมาะสม - และตอนนี้ระดับใด ๆ ที่ดำเนินการที่อินเตอร์เฟซที่จะทำให้คุณรายการของมัน (หมายเหตุ.iteritems()
จะหายไปในหลาม 3):
try:
items = any_object.items()
except (AttributeError, TypeError):
non_items_behavior(any_object)
else: # no exception raised
for item in items: ...
บางทีคุณอาจคิดว่าการใช้การพิมพ์เป็ดแบบนี้ไปไกลเกินกว่าจะยอมให้มีผลบวกปลอมมากเกินไปและอาจขึ้นอยู่กับวัตถุประสงค์ของรหัสนี้
ข้อสรุป
อย่าใช้is
เพื่อตรวจสอบประเภทของโฟลว์การควบคุมมาตรฐาน ใช้isinstance
พิจารณา abstractions เช่นMapping
หรือMutableMapping
และพิจารณาหลีกเลี่ยงการตรวจสอบชนิดโดยใช้อินเตอร์เฟสโดยตรง