จำไว้ว่าใน Python เราต้องการใช้ "การพิมพ์เป็ด" ดังนั้นสิ่งใดก็ตามที่ทำหน้าที่เหมือนรายการจึงถือว่าเป็นรายการได้ ดังนั้นอย่าตรวจสอบประเภทของรายการเพียงดูว่ามันทำหน้าที่เหมือนกับรายการหรือไม่
แต่สายอักขระทำหน้าที่เหมือนรายการเช่นกันและบ่อยครั้งนั้นไม่ใช่สิ่งที่เราต้องการ มีบางครั้งที่มันเป็นปัญหา! ดังนั้นตรวจสอบสตริงอย่างชัดเจน แต่จากนั้นใช้การพิมพ์เป็ด
นี่คือฟังก์ชั่นที่ฉันเขียนเพื่อความสนุก มันเป็นรุ่นพิเศษrepr()
ที่พิมพ์ลำดับใด ๆ ในวงเล็บมุม ('<', '>')
def srepr(arg):
if isinstance(arg, basestring): # Python 3: isinstance(arg, str)
return repr(arg)
try:
return '<' + ", ".join(srepr(x) for x in arg) + '>'
except TypeError: # catch when for loop fails
return repr(arg) # not a sequence so just return repr
นี่คือสะอาดและสง่างามโดยรวม แต่สิ่งที่isinstance()
ตรวจสอบทำที่นั่น? นั่นคือการแฮ็ค แต่มันเป็นสิ่งสำคัญ
ฟังก์ชั่นนี้เรียกตัวเองซ้ำในสิ่งที่ทำหน้าที่เหมือนรายการ หากเราไม่ได้จัดการกับสายอักขระโดยเฉพาะมันจะได้รับการปฏิบัติเหมือนเป็นรายการและแยกอักขระทีละตัว แต่แล้วการโทรซ้ำจะพยายามรักษาตัวละครแต่ละตัวเป็นรายการ - และมันก็ใช้ได้ แม้แต่สตริงตัวละครเดียวก็ใช้เป็นรายการได้! ฟังก์ชั่นจะยังคงเรียกตัวเองซ้ำ ๆ จนกว่าจะล้นสแต็ค
ฟังก์ชั่นเช่นนี้ที่ขึ้นอยู่กับการเรียกซ้ำแต่ละครั้งเพื่อแยกแยะงานที่ต้องทำต้องใช้สตริงตัวพิมพ์เล็ก - เพราะคุณไม่สามารถแยกสตริงที่ต่ำกว่าระดับของสตริงอักขระหนึ่งตัวและแม้แต่อันเดียว สตริงอักขระทำหน้าที่เหมือนรายการ
หมายเหตุ: try
/ except
เป็นวิธีที่สะอาดที่สุดในการแสดงเจตนาของเรา แต่ถ้ารหัสนี้มีความสำคัญต่อเวลาเราอาจต้องการแทนที่ด้วยการทดสอบบางประเภทเพื่อดูว่าarg
เป็นลำดับหรือไม่ แทนที่จะทดสอบประเภทเราควรทดสอบพฤติกรรม ถ้ามันมี.strip()
เมธอดมันเป็นสตริงดังนั้นอย่าคิดว่ามันเป็นลำดับ มิฉะนั้นหากสามารถทำดัชนีได้หรือทำซ้ำได้ก็เป็นลำดับ:
def is_sequence(arg):
return (not hasattr(arg, "strip") and
hasattr(arg, "__getitem__") or
hasattr(arg, "__iter__"))
def srepr(arg):
if is_sequence(arg):
return '<' + ", ".join(srepr(x) for x in arg) + '>'
return repr(arg)
แก้ไข: เดิมฉันเขียนข้างต้นด้วยการตรวจสอบ__getslice__()
แต่ฉันสังเกตเห็นว่าในcollections
เอกสารประกอบโมดูลวิธีที่น่าสนใจคือ__getitem__()
; มันสมเหตุสมผลแล้วนั่นคือวิธีที่คุณจัดทำดัชนีวัตถุ ที่ดูเหมือนพื้นฐานมากกว่า__getslice__()
ดังนั้นฉันเปลี่ยนข้างต้น