วิธีมาตรฐานในการตรวจสอบประเภทใน Python คืออะไร


1277

เป็นวิธีที่ดีที่สุดในการตรวจสอบว่าวัตถุที่กำหนดเป็นประเภทที่กำหนดคืออะไร? วิธีการเกี่ยวกับการตรวจสอบว่าวัตถุสืบทอดจากประเภทที่กำหนดหรือไม่

oสมมติว่าผมมีวัตถุ ฉันจะตรวจสอบว่ามันเป็นstrอย่างไร


7
วิธีการแบบบัญญัติใน Python คือไม่ต้องตรวจสอบประเภทเลย (เว้นแต่คุณจะทำการดีบั๊ก) โดยปกติแล้วคุณเพียงแค่พยายามใช้มันเป็นสตริง (เช่นเชื่อมโยงกับสตริงอื่น ๆ พิมพ์ไปที่คอนโซล ฯลฯ ); หากคุณคิดว่าอาจล้มเหลวให้ลองใช้ / ยกเว้นหรือ Hasattr นั่นคือคำตอบที่ได้รับการยอมรับเป็นวิธีบัญญัติในการทำสิ่งที่คุณมักจะ "ไม่ควรทำ" ในโลกหลาม สำหรับข้อมูลเพิ่มเติมให้ google "พิมพ์ Python เป็ด" หรืออ่านสิ่งเหล่านี้: voidspace.org.uk/python/articles/duck_typing.shtml stackoverflow.com/questions/610883/ …
Jon Coombs

9
ฉันคิดว่า Mr. Coombs มองเห็นตัวอย่างเช่นคลาสที่ไม่ต่อเนื่องของ JSON หากใส่ข้อมูลจำนวนมากผ่านฟังก์ชั่น (ซึ่งโค้ดหนึ่งไม่สามารถมีอิทธิพลต่อ) หนึ่งอาจต้องการแปลงบางส่วนของข้อมูลที่เป็นตัวอย่างเช่น <str> ก่อนที่จะผ่านมัน อย่างน้อยนั่นก็เป็นวิธีที่ฉันลงเอยในหน้านี้ ...
John Carrell

2
ดูเหมือนว่าสาเหตุที่พบบ่อยที่สุดสำหรับการขอนี้คือหนึ่งต้องการแยกความแตกต่างระหว่างสตริงและ iterables ของสตริง นี่เป็นคำถามที่ยุ่งยากเพราะสตริงนั้นเป็นสตริงที่ซ้ำซ้อน - สตริงอักขระเดี่ยวเป็นลำดับของตัวเอง (ครั้งล่าสุดที่ฉันตรวจสอบ - หนึ่งอาจไม่ควรพึ่งพามัน) แต่ทุกคนจะเคยใช้สิ่งที่เหมือนสตริงหรือไม่? ใช่แล้ว ดังนั้นคำตอบของ "ฉันควรทำอย่างไรเพื่อแยกความแตกต่างระหว่างสตริงและตัวทำซ้ำสตริงอื่น ๆ " ถูกต้อง: "ขึ้นอยู่กับสิ่งที่คุณพยายามจะทำ" :-D
clacke

2
การเพิ่มความคิดเห็นชนิด Python เป็นสิ่งสำคัญ ดูmypy
Sheena

คำตอบ:


1522

ในการตรวจสอบว่าoเป็นอินสแตนซ์ของstrหรือคลาสย่อยใด ๆstrให้ใช้isinstance (นี่จะเป็นวิธี "canonical"):

if isinstance(o, str):

ในการตรวจสอบว่าประเภทของประเภทoนั้นแน่นอนstrหรือไม่ (ยกเว้นคลาสย่อย):

if type(o) is str:

ต่อไปนี้ใช้งานได้และอาจมีประโยชน์ในบางกรณี:

if issubclass(type(o), str):

ดูฟังก์ชั่นในตัวใน Python Library Reference สำหรับข้อมูลที่เกี่ยวข้อง

อีกหนึ่งหมายเหตุ: ในกรณีนี้ถ้าคุณใช้ Python 2 คุณอาจต้องการใช้:

if isinstance(o, basestring):

เพราะสิ่งนี้จะจับสตริง Unicode ( unicodeไม่ใช่คลาสย่อยของstr; ทั้งคู่strและunicodeคลาสย่อยของbasestring) โปรดทราบว่าbasestringไม่มีอยู่ใน Python 3 อีกต่อไปโดยที่มีการแยกสตริง ( str) และข้อมูลไบนารี ( bytes) อย่างเข้มงวด

อีกทางเลือกหนึ่งisinstanceรับของชั้นเรียน สิ่งนี้จะส่งคืนTrueหากoเป็นอินสแตนซ์ของคลาสย่อยใด ๆ ของ(str, unicode):

if isinstance(o, (str, unicode)):

31
str .__ subclasses __ () ส่งคืน subclasses โดยตรงของ str เท่านั้นและไม่ได้ทำสิ่งเดียวกันกับ issubclass () หรือ isinstance () (ในการทำเช่นนั้นคุณจะต้องเรียกคลาสย่อย. __ ซ้ำ) __ ()
โทมัสวูสเตอร์

15
นี่เป็นคำตอบที่ดี แต่ฉันคิดว่าควรเริ่มต้นด้วยคำเตือนว่าคุณไม่ควรทำสิ่งนี้ใน Python ตามที่เป็นอยู่ดูเหมือนว่าจะตรวจสอบสมมติฐานที่ว่านี่เป็น "สิ่งที่ยอมรับได้ใน Python" ซึ่งไม่ใช่
Jon Coombs

4
เหล่านี้คือคำตอบของ python2 ตัวอย่างเช่นไม่มี basestring ใน python3
dfrankow

4
ความแตกต่างระหว่างอินสแตนซ์และ "แน่นอน" คืออะไร หากแล้วไม่ได้มันก็จริงที่ว่าtype(a) is Object isinstance(a, Object)แต่ถ้าtype(a) is SubClassOfObjectไปแล้ว แต่type(a) is Object == False isinstance(a, Object) == Trueขวา?
mavavilj

1
@mavavilj - a is bหมายถึง a และ b เป็นสิ่งเดียวกันนั่นคือการอ้างอิงไปยังเอนทิตีเดียวกันในหน่วยความจำ ดังนั้นaและbจะต้องเป็นระดับเดียวกันที่แน่นอนไม่ได้ subclasses isinstance()เช่นเดียวกับ ดูตัวอย่างstackoverflow.com/a/133024/1072212
เทอร์รี่บราวน์

196

ที่สุดวิธี Pythonic เพื่อตรวจสอบชนิดของวัตถุคือ ... ไม่ได้ไปตรวจสอบ

เนื่องจาก Python สนับสนุนการพิมพ์ดีดเป็ดคุณจึงควรtry...exceptใช้วิธีการของวัตถุในแบบที่คุณต้องการใช้ ดังนั้นหากฟังก์ชั่นของคุณกำลังมองหาวัตถุไฟล์ที่เขียนได้อย่าตรวจสอบว่ามันเป็นซับคลาสของfileเพียงลองใช้.write()วิธีการของมัน!

แน่นอนว่าบางครั้ง abstractions ที่ดีเหล่านี้ก็พังทลายและisinstance(obj, cls)เป็นสิ่งที่คุณต้องการ แต่ใช้เท่าที่จำเป็น


75
IMHO วิธี Pythonic ที่มากที่สุดคือการรับมือกับข้อโต้แย้งใด ๆ ที่ได้รับ ในรหัสของฉันฉันมักจะไม่ทราบว่าฉันได้รับวัตถุหรืออาร์เรย์ของวัตถุและฉันใช้การตรวจสอบประเภทภายในเพื่อแปลงวัตถุเดียวเป็นรายการองค์ประกอบเดียว
sastanin

14
แทนที่จะลองใช้วิธีการเขียนมันมีหลายครั้งที่คุณต้องการทำสิ่งนี้โดยไม่ทำให้เกิดข้อยกเว้น ในกรณีนี้คุณสามารถทำได้ ... if hasattr(ob, "write") and callable(ob.write): หรือบันทึกการเข้าถึง dict ...func = getattr(ob, "write", None) if callable(func): ...
ideasman42

142
การพิมพ์เป็ดเป็นเรื่องเกี่ยวกับการใช้ห้องสมุด การตรวจสอบประเภทเป็นเรื่องเกี่ยวกับการเขียนห้องสมุด ไม่ใช่โดเมนปัญหาเดียวกัน
RickyA

16
@RickyA ฉันไม่เห็นด้วย การพิมพ์เป็ดเป็นเรื่องเกี่ยวกับการโต้ตอบกับวัตถุโดยใช้อินเตอร์เฟสที่มีความหมายที่รู้จักกันดี สิ่งนี้สามารถนำไปใช้กับรหัสห้องสมุดหรือรหัสที่ใช้ห้องสมุดดังกล่าว
Dan Lenski

6
@ nyuszika7h ใน Python3 hasattrจะมีเฉพาะ AttributeError เท่านั้น - ดูที่: docs.python.org/3.4/library/functions.html#hasattr
ideasman42

57

isinstance(o, str)จะกลับมาTrueถ้าoเป็นหรือเป็นประเภทที่สืบทอดมาจากstrstr

type(o) is strจะกลับมาTrueถ้าหากว่าoเป็น STR มันจะกลับมาFalseถ้าเป็นประเภทที่สืบทอดมาจากostr


6
แน่นอนว่าสิ่งนี้จะล้มเหลวหากวัตถุไม่ใช่ตัวอย่างของ 'str' แต่มีบางอย่างที่เป็นสตริงแทน เช่น unicode, mmap, UserString หรือประเภทอื่น ๆ ที่ผู้ใช้กำหนด วิธีการตามปกติใน Python ไม่ต้องทำการพิมพ์
Thomas Wouters

6
คุณไม่ต้องขอโทษมันก็โอเคที่จะตอบคำถามของคุณเอง ดังนั้นสำหรับคำตอบไม่ใช่กรรม
Eli Bendersky

2
สิ่งนี้มีประโยชน์มาก เพราะความแตกต่างระหว่างisinstanceและtype(var) == type('')ไม่ชัดเจน
sastanin

30

หลังจากคำถามที่ถูกถามและตอบชนิดคำแนะนำที่ถูกเพิ่มเข้าไปในหลาม พิมพ์คำใบ้ใน Python อนุญาตให้ตรวจสอบประเภท แต่แตกต่างจากภาษาที่พิมพ์แบบคงที่ คำใบ้ประเภทใน Python จะเชื่อมโยงประเภทของอาร์กิวเมนต์ที่คาดหวังกับฟังก์ชั่นเป็นข้อมูลที่สามารถเข้าถึงได้ที่เชื่อมโยงกับฟังก์ชั่นรันไทม์ซึ่งจะช่วยให้สามารถตรวจสอบประเภทได้ ตัวอย่างของไวยากรณ์คำใบ้ประเภท:

def foo(i: int):
    return i

foo(5)
foo('oops')

ในกรณีนี้เราต้องการให้เกิดข้อผิดพลาดที่จะถูกเรียกสำหรับตั้งแต่ประเภทข้อเขียนของการโต้แย้งคือfoo('oops') intคำใบ้ประเภทที่เพิ่มเข้ามาจะไม่ทำให้เกิดข้อผิดพลาดเกิดขึ้นเมื่อสคริปต์ทำงานตามปกติ อย่างไรก็ตามมันเพิ่มคุณสมบัติให้กับฟังก์ชั่นที่อธิบายถึงประเภทที่คาดหวังว่าโปรแกรมอื่นสามารถสืบค้นและใช้เพื่อตรวจสอบข้อผิดพลาดประเภท

หนึ่งในโปรแกรมอื่น ๆ เหล่านี้ที่สามารถใช้เพื่อค้นหาข้อผิดพลาดประเภทคือmypy:

mypy script.py
script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"

(คุณอาจต้องติดตั้งmypyจากผู้จัดการแพ็คเกจฉันไม่คิดว่ามันมาพร้อมกับ CPython แต่ดูเหมือนจะมี "ทางการ" ในระดับหนึ่ง)

การตรวจสอบประเภทด้วยวิธีนี้แตกต่างจากการตรวจสอบประเภทในภาษาที่รวบรวมแบบคงที่ เนื่องจากประเภทเป็นแบบไดนามิกใน Python การตรวจสอบประเภทจะต้องทำที่รันไทม์ซึ่งกำหนดค่าใช้จ่าย - แม้ในโปรแกรมที่ถูกต้อง - ถ้าเรายืนยันว่ามันเกิดขึ้นในทุกโอกาส การตรวจสอบประเภทที่ชัดแจ้งอาจมีข้อ จำกัด มากกว่าที่จำเป็นและทำให้เกิดข้อผิดพลาดที่ไม่จำเป็น (เช่นอาร์กิวเมนต์จำเป็นต้องเป็นlistประเภทที่แน่นอนหรือเป็นสิ่งที่สามารถทำซ้ำได้หรือไม่?)

ข้อดีของการตรวจสอบประเภทที่ชัดเจนคือมันสามารถตรวจจับข้อผิดพลาดก่อนหน้านี้และให้ข้อความแสดงข้อผิดพลาดที่ชัดเจนกว่าการพิมพ์เป็ด ข้อกำหนดที่แน่นอนของประเภทเป็ดสามารถแสดงด้วยเอกสารภายนอกเท่านั้น (หวังว่ามันจะละเอียดและแม่นยำ) และข้อผิดพลาดจากประเภทที่เข้ากันไม่ได้สามารถเกิดขึ้นได้ไกลจากที่มา

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

typingตัวแปรประเภทแพคเกจข้อเสนอพิเศษที่สามารถนำมาใช้ในคำแนะนำที่เป็นประเภทที่จะแสดงพฤติกรรมที่จำเป็นโดยไม่ต้องมีประเภทโดยเฉพาะอย่างยิ่ง ตัวอย่างเช่นมันมีตัวแปรเช่นIterableและCallableคำแนะนำเพื่อระบุความต้องการประเภทใด ๆ ที่มีพฤติกรรมเหล่านั้น

ในขณะที่คำแนะนำประเภทเป็นวิธีการตรวจสอบชนิดของงูเหลือมที่มากที่สุด แต่บ่อยครั้งที่ Pythonic ชนิดนี้ไม่สามารถตรวจสอบประเภทได้ทั้งหมดและพึ่งพาการพิมพ์เป็ด คำใบ้ประเภทนี้ค่อนข้างใหม่และคณะลูกขุนยังคงปรากฏต่อไปเมื่อเป็น Pythonic solution ที่สุด การเปรียบเทียบที่ค่อนข้างไม่มีข้อโต้แย้ง แต่โดยทั่วไปมาก: คำแนะนำประเภทให้รูปแบบของเอกสารที่สามารถบังคับใช้อนุญาตให้สร้างรหัสก่อนหน้านี้และง่ายต่อการเข้าใจข้อผิดพลาดสามารถจับข้อผิดพลาดที่พิมพ์เป็ดไม่สามารถและสามารถตรวจสอบแบบคงที่ ความรู้สึก แต่มันยังคงอยู่นอกรันไทม์) ในทางกลับกันการพิมพ์เป็ดเป็นวิธี Pythonic มาเป็นเวลานานไม่ได้กำหนดค่าใช้จ่ายทางปัญญาของการพิมพ์แบบสแตติกมีความละเอียดน้อยกว่าและยอมรับทุกประเภทที่ใช้ได้


2
-1: mypyเรียกตัวเองว่า "ตัวตรวจสอบชนิดคงที่" โดยเฉพาะดังนั้นฉันไม่แน่ใจว่าคุณได้รับ "การตรวจสอบประเภทต้องทำที่รันไทม์" จาก
เควิน

@Kevin ในการหวนกลับนั่นเป็นการพูดนอกเรื่องที่ไม่จำเป็น แต่เพื่อให้ได้คำแนะนำที่มากขึ้นของไพ ธ อนกลับกลายเป็นข้อมูลรันไทม์และmypyเป็นโมดูล Python ที่ใช้importlibในการเข้าถึงข้อมูลนั้น ไม่ว่าจะเป็น "การตรวจสอบประเภทคงที่" เป็นคำถามเชิงปรัชญา แต่แตกต่างจากสิ่งที่คาดหวังมากที่สุดเนื่องจากล่ามภาษาปกติและเครื่องจักรนำเข้ามีส่วนเกี่ยวข้อง
Praxeolitic

4
นั่นไม่เป็นความจริงเช่นกัน มันใช้ typed_ast ซึ่งตัวเองเป็นเพียงโคลนของ ast ที่มีคุณสมบัติพิเศษ astไม่ได้นำเข้าโมดูล มันแยกพวกเขาเป็นต้นไม้ไวยากรณ์ที่เป็นนามธรรม
เควิน

18

นี่คือตัวอย่างว่าทำไมการพิมพ์เป็ดจึงเป็นเรื่องที่ชั่วร้ายโดยที่ไม่รู้ว่ามันอันตรายเมื่อไร ตัวอย่างเช่น: นี่คือรหัส Python (อาจเว้นการเยื้องที่เหมาะสม) โปรดทราบว่าสถานการณ์นี้สามารถหลีกเลี่ยงได้โดยการดูแล isinstance และ issubclassof เพื่อให้แน่ใจว่าเมื่อคุณต้องการเป็ดจริง ๆ คุณจะไม่ได้รับระเบิด

class Bomb:
    def __init__(self):
        ""

    def talk(self):
        self.explode()

    def explode(self):
        print "BOOM!, The bomb explodes."

class Duck:
    def __init__(self):
        ""
    def talk(self):
        print "I am a duck, I will not blow up if you ask me to talk."    

class Kid:
    kids_duck = None

    def __init__(self):
        print "Kid comes around a corner and asks you for money so he could buy a duck."

    def takeDuck(self, duck):
        self.kids_duck = duck
        print "The kid accepts the duck, and happily skips along"

    def doYourThing(self):
        print "The kid tries to get the duck to talk"
        self.kids_duck.talk()

myKid = Kid()
myBomb = Bomb()
myKid.takeDuck(myBomb)
myKid.doYourThing()

36
แม้จะมีการตรวจสอบประเภทคุณสามารถสร้างclass EvilDuck(Duck)และแทนที่พูดคุย () หรือมีโอกาสมากขึ้นที่มีclass ChineseCancerDuck(Duck)ผลข้างเคียงที่น่ารังเกียจซึ่งไม่ปรากฏขึ้นจนกว่าจะถึงปีต่อมา คุณควรจะดูแลลูกของคุณให้ดีขึ้น (และทดสอบของเล่นของเธออย่างถี่ถ้วน :)
Brett Thomas

36
ลูกระเบิดไม่พูด อย่าเพิ่มวิธีที่ไร้สาระและสิ่งนี้จะไม่เกิดขึ้น
rightfold

7
@Dmitry นี่คือคำวิจารณ์ทั่วไปของ Duck Typing: en.wikipedia.org/wiki/Duck_typing#คำติชม... โดยพื้นฐานแล้วคุณกำลังพูดว่าอินเทอร์เฟซใด ๆ ที่ความหมายไม่ได้บังคับโดยภาษานั้นเป็นสิ่งชั่วร้าย ฉันเชื่อว่านี่เป็นแนวทางของ Java มากกว่า จุดรวมของการพิมพ์เป็ดของ Python คือมันใช้ได้เฉพาะเมื่อมีการประชุมทั่วไปเกี่ยวกับความหมายของอินเตอร์เฟสเฉพาะ ตัวอย่างเช่นคุณสามารถบอร์โค้ด Python จำนวนมากโดยการแทนที่__file__แอ็ตทริบิวต์ (โดยทั่วไปจะใช้เพื่อระบุออบเจ็กต์คล้ายไฟล์) เพื่อแปลความหมายอย่างอื่น
Dan Lenski

2
ทั้งหมดนี้มาจากเรื่องตลกเก่า ๆ "หมอมันเจ็บเมื่อฉันทำอย่างนี้" ... "จากนั้นอย่าทำอย่างนั้น" ไม่น่าพอใจสำหรับใครบางคนที่คุ้นเคยกับ "ถ้ามันรวบรวมมันจะทำงาน" แต่นั่นเป็นสาเหตุที่การทดสอบความหลงใหลเกิดขึ้นจากโลกแห่งภาษาที่มีพลวัต
clacke

1
@clacke โดยพื้นฐานแล้วมันแพงเกินไปที่จะบังคับประเภทที่รันไทม์อย่างเคร่งครัดเพราะทุกอย่างจะต้องเป็นวัตถุ (เพื่อแมปจากสตริงกับประเภทใด ๆ ที่เป็นไปได้) และสะดวกเกินไปที่จะไม่มี Ducktyping เพราะ ducktyping ช่วยให้เทคนิคการสร้างต้นแบบที่ทรงพลังจริงๆ โดยทั่วไปแล้วจะยากมากที่จะทำกับอินเตอร์เฟซที่เข้มงวด นอกจากนี้ภาษาแบบสแตติกใด ๆ ก็ต้องเผชิญกับจุดที่จำเป็นต้องสร้างการพิมพ์เป็ดผ่านห้องสมุดแบบไดนามิกการประเมินและการสร้างสตริงหรืออินเทอร์เฟซและสิ่งเหล่านี้ไม่ได้ทำให้มันชั่วร้าย
Dmitry

12

1
แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงค์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงนั้นเปลี่ยนแปลง
EKons

7

ฉันคิดว่าสิ่งที่ยอดเยี่ยมเกี่ยวกับการใช้ภาษาแบบไดนามิกเช่น Python คือคุณไม่ควรตรวจสอบสิ่งนั้น

ฉันแค่จะเรียกวิธีการที่จำเป็นในวัตถุของคุณและจับ AttributeErrorฉันจะเรียกวิธีการที่จำเป็นบนวัตถุและจับของคุณหลังจากนี้จะช่วยให้คุณสามารถเรียกวิธีการของคุณกับวัตถุอื่น ๆ (ดูเหมือนไม่เกี่ยวข้อง) เพื่อทำงานที่แตกต่างกันเช่นการเยาะเย้ยวัตถุสำหรับการทดสอบ

ฉันใช้มันเยอะมากเมื่อนำข้อมูลออกจากเว็บurllib2.urlopen()ซึ่งคืนไฟล์เหมือนวัตถุ สิ่งนี้สามารถส่งผ่านไปยังเกือบทุกวิธีที่อ่านจากไฟล์เพราะมันใช้read()วิธีการเดียวกันกับไฟล์จริง

แต่ฉันแน่ใจว่ามีเวลาและสถานที่สำหรับการใช้isinstance()งานมิฉะนั้นมันอาจจะไม่อยู่ที่นั่น :)


ตัวอย่างที่ดีของเวลาที่คุณต้องใช้คือถ้าคุณกำลังวิเคราะห์คำอ็อบเจ็กต์ json แบบไดนามิก คุณไม่ทราบล่วงหน้าหากฟิลด์เป็นสตริงหรือพจนานุกรม
สีเทา

6

สำหรับการตรวจสอบประเภทที่ซับซ้อนยิ่งขึ้นฉันชอบวิธีการตรวจสอบของtypeguardโดยอ้างอิงจากคำอธิบายประกอบแบบ python:

from typeguard import check_type
from typing import List

try:
    check_type('mylist', [1, 2], List[int])
except TypeError as e:
    print(e)

คุณสามารถทำการตรวจสอบที่ซับซ้อนมากในแบบที่สะอาดและอ่านง่าย

check_type('foo', [1, 3.14], List[Union[int, float]])
# vs
isinstance(foo, list) and all(isinstance(a, (int, float)) for a in foo) 

6

คุณสามารถตรวจสอบประเภทของตัวแปรโดยใช้ __name__ ของประเภท

Ex:

>>> a = [1,2,3,4]  
>>> b = 1  
>>> type(a).__name__
'list'
>>> type(a).__name__ == 'list'
True
>>> type(b).__name__ == 'list'
False
>>> type(b).__name__
'int'

ขอบคุณนี่เป็นรหัสลับที่ฉันต้องการเมื่อฉันแสดงมันเป็นความคิดเห็นกับผู้ใช้ ผมใช้เวลานานในการค้นหานี้ ...
แอรอน D. Marasco

5

ถึงฮูโก้:

คุณอาจหมายถึงlistมากกว่าarrayแต่ชี้ไปที่ปัญหาทั้งหมดด้วยการตรวจสอบชนิด - คุณไม่ต้องการทราบว่าวัตถุที่เป็นปัญหานั้นเป็นรายการหรือไม่คุณต้องการทราบว่าเป็นลำดับหรือไม่หรือเป็นวัตถุเดียว ดังนั้นลองใช้มันเหมือนลำดับ

สมมติว่าคุณต้องการเพิ่มวัตถุในลำดับที่มีอยู่หรือถ้าเป็นลำดับของวัตถุให้เพิ่มทั้งหมด

try:
   my_sequence.extend(o)
except TypeError:
  my_sequence.append(o)

เคล็ดลับอย่างหนึ่งก็คือถ้าคุณกำลังทำงานกับสตริงและ / หรือลำดับของสตริง - นั่นเป็นเรื่องยากเนื่องจากสตริงมักจะคิดว่าเป็นวัตถุเดียว แต่ก็เป็นลำดับของตัวละครด้วยเช่นกัน ยิ่งไปกว่านั้นเนื่องจากเป็นลำดับของสตริงความยาวเดี่ยว

ฉันมักจะเลือกที่จะออกแบบ API ของฉันเพื่อที่จะยอมรับเฉพาะค่าเดียวหรือลำดับ - มันทำให้ง่ายขึ้น มันไม่ยากเลยที่จะใส่[ ]ค่าเดียวของคุณเมื่อคุณผ่านมันหากจำเป็น

(แม้ว่าสิ่งนี้อาจทำให้เกิดข้อผิดพลาดกับสตริงได้เนื่องจากมีลักษณะดังนี้ (เป็น) ลำดับ)


0

วิธีง่ายๆในการตรวจสอบประเภทคือการเปรียบเทียบกับสิ่งที่คุณรู้ประเภท

>>> a  = 1
>>> type(a) == type(1)
True
>>> b = 'abc'
>>> type(b) == type('')
True

-1

ฉันคิดว่าวิธีที่ดีที่สุดคือการพิมพ์ตัวแปรของคุณให้ดี คุณสามารถทำได้โดยใช้ห้องสมุด "พิมพ์"

ตัวอย่าง:

from typing import NewType UserId = NewType ('UserId', int) some_id = UserId (524313) `

ดูhttps://docs.python.org/3/library/typing.html


-7

คุณสามารถตรวจสอบกับบรรทัดด้านล่างเพื่อตรวจสอบประเภทของตัวอักษรที่ได้รับค่าคือ:

def chr_type(chrx):
    if chrx.isalpha()==True:
        return 'alpha'
    elif chrx.isdigit()==True:
        return 'numeric'
    else:
        return 'nothing'

chr_type("12)

3
คุณแน่ใจหรือไม่ว่าต้องการลบคำตอบนี้ @Venkatesan
สีเทา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.