กำหนดประเภทของวัตถุ?


1791

มีวิธีง่ายๆในการพิจารณาว่าตัวแปรเป็นรายการพจนานุกรมหรืออย่างอื่นหรือไม่? ฉันได้รับวัตถุคืนซึ่งอาจเป็นประเภทใดประเภทหนึ่งและฉันต้องสามารถบอกความแตกต่างได้


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

67
@ S.Lott ฉันไม่เห็นด้วย ด้วยความสามารถในการรู้ประเภทคุณสามารถจัดการกับตัวแปรที่หลากหลายและยังคงทำสิ่งที่ถูกต้องได้ มันช่วยให้คุณหลีกเลี่ยงปัญหาเกี่ยวกับอินเทอร์เฟซโดยอาศัยการพิมพ์เป็ดแท้ (เช่นวิธีการ. bark) บนต้นไม้หมายถึงบางสิ่งที่แตกต่างจาก Dog อย่างสิ้นเชิงตัวอย่างเช่นคุณสามารถสร้างฟังก์ชั่นที่ทำงานบางอย่าง ไฟล์ที่ยอมรับสตริง (เช่นพา ธ ) วัตถุพา ธ หรือรายการ ทุกคนมีอินเตอร์เฟสที่ต่างกัน แต่ผลลัพธ์สุดท้ายเหมือนกัน: ทำการดำเนินการบางอย่างกับไฟล์นั้น
Robert P

22
@ S.Lott ฉันหวังว่ามันจะเห็นได้ชัดว่ามันเป็นตัวอย่างที่วางแผนไว้; อย่างไรก็ตามมันเป็นจุดล้มเหลวที่สำคัญของการพิมพ์เป็ดและเป็นสิ่งที่tryไม่ช่วยด้วย ตัวอย่างเช่นหากคุณรู้ว่าผู้ใช้สามารถส่งผ่านสตริงหรืออาร์เรย์ทั้งคู่สามารถใช้ดัชนีได้ แต่ดัชนีนั้นหมายถึงบางสิ่งที่แตกต่างอย่างสิ้นเชิง เพียงพึ่งพาการลองในกรณีเหล่านี้จะล้มเหลวในรูปแบบที่ไม่คาดคิดและแปลก ทางออกหนึ่งคือการสร้างวิธีแยกต่างหากอีกวิธีหนึ่งเพื่อเพิ่มการตรวจสอบประเภทเล็กน้อย ผมเองชอบพฤติกรรม polymorphic กว่าวิธีการหลายอย่างที่ทำเกือบสิ่งเดียวกัน ... แต่นั่นเป็นเพียงฉัน :)
โรเบิร์ต P

22
@ S.Lott การทดสอบหน่วยเป็นอย่างไร บางครั้งคุณต้องการให้การทดสอบของคุณตรวจสอบว่าฟังก์ชันส่งคืนบางอย่างที่ถูกต้อง ตัวอย่างจริงมากคือเมื่อคุณมีโรงงานคลาส
Elliot Cameron

17
สำหรับตัวอย่างที่ไม่ได้วางแผนให้พิจารณา serializer / deserializer ตามคำนิยามคุณกำลังแปลงระหว่างวัตถุที่ผู้ใช้กำหนดและการแสดงแบบอนุกรม serializer จำเป็นต้องกำหนดประเภทของวัตถุที่คุณผ่านและคุณอาจมีข้อมูลไม่เพียงพอที่จะกำหนดประเภท deserialized โดยไม่ต้องขอ runtime (หรืออย่างน้อยที่สุดคุณอาจต้องใช้มันสำหรับการตรวจสอบสติเพื่อจับข้อมูลที่ไม่ดีก่อนที่มันจะเข้า ระบบของคุณ!)
Karl

คำตอบ:


1976

มีฟังก์ชันในตัวสองตัวที่ช่วยคุณระบุประเภทของวัตถุ คุณสามารถใช้type() ถ้าคุณต้องการชนิดของวัตถุที่แน่นอนและisinstance()เพื่อตรวจสอบชนิดของวัตถุกับบางสิ่งบางอย่าง โดยปกติแล้วคุณต้องการใช้เวลาisistance()ส่วนใหญ่เนื่องจากมีความทนทานและรองรับการสืบทอดประเภท


ในการรับชนิดของวัตถุที่แท้จริงคุณใช้type()ฟังก์ชันในตัว ผ่านวัตถุเป็นพารามิเตอร์เท่านั้นที่จะส่งกลับประเภทวัตถุของวัตถุนั้น:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

หลักสูตรนี้ใช้ได้กับประเภทที่กำหนดเองด้วย:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

โปรดทราบว่าtype()จะส่งคืนวัตถุประเภททันที แต่จะไม่สามารถบอกคุณเกี่ยวกับการสืบทอดประเภท

>>> type(b) is Test1
False

เพื่อให้ครอบคลุมนั้นคุณควรใช้isinstanceฟังก์ชั่น แน่นอนนี้ยังใช้งานได้กับชนิดในตัว:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

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

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

>>> isinstance([], (tuple, list, set))
True

68
ฉันคิดว่ามันชัดเจนกว่าที่จะใช้isแทนที่จะ==เป็นแบบซิงเกิล
John La Rooy

18
@gnibbler, ในกรณีที่คุณจะได้รับการ typechecking (ซึ่งคุณไม่ควรทำจะเริ่มต้นด้วย) isinstanceเป็นรูปแบบที่ต้องการ แต่อย่างใดดังนั้นไม่==หรือisจำเป็นต้องใช้
Mike Graham

23
@ ไมค์เกรแฮมมีบางครั้งtypeที่คำตอบที่ดีที่สุดคือ มีบางครั้งisinstanceที่คำตอบที่ดีที่สุดและมีบางครั้งที่การพิมพ์เป็ดเป็นคำตอบที่ดีที่สุด เป็นสิ่งสำคัญที่จะต้องทราบตัวเลือกทั้งหมดเพื่อให้คุณสามารถเลือกตัวเลือกที่เหมาะสมกับสถานการณ์
John La Rooy

6
@gnibbler, นั่นอาจจะเป็น แต่ผมยังไม่ได้วิ่งเข้าไปในสถานการณ์ที่จะดีกว่าtype(foo) is SomeType isinstance(foo, SomeType)
Mike Graham

5
@poke: ฉันเห็นด้วยอย่างยิ่งกับ PEP8 แต่คุณกำลังโจมตีชาวฟางที่นี่: ส่วนสำคัญของการโต้แย้งของ Sven ไม่ใช่ PEP8 แต่คุณสามารถใช้isinstanceสำหรับ usecase ของคุณได้ (เช่นการตรวจสอบประเภทต่างๆ) และด้วย ทำความสะอาดไวยากรณ์เช่นกันซึ่งมีข้อดีมากที่คุณสามารถจับคลาสย่อยได้ บางคนที่ใช้OrderedDictจะเกลียดโค้ดของคุณที่จะล้มเหลวเพราะมันแค่ยอมรับ dicts ที่บริสุทธิ์
แกะบินได้


40

อาจเป็น Pythonic มากกว่านี้ในการใช้try... exceptblock วิธีการที่ถ้าคุณมีระดับซึ่ง quacks เช่นรายการหรือ quacks เช่น Dict ที่มันจะทำงานได้อย่างถูกต้องโดยไม่คำนึงถึงสิ่งที่ประเภทของมันจริงๆคือ

เพื่อชี้แจงวิธีการที่ต้องการ "บอกความแตกต่าง" ระหว่างประเภทตัวแปรคือสิ่งที่เรียกว่าการพิมพ์เป็ด : ตราบใดที่วิธีการ (และประเภทที่ส่งคืน) ที่ตัวแปรตอบสนองเป็นสิ่งที่รูทีนย่อยของคุณคาดหวัง เป็น. ตัวอย่างเช่นหากคุณมีคลาสที่ใช้ตัวดำเนินการวงเล็บปีกกาเกินgetattrและsetattrแต่ใช้รูปแบบภายในตลกบางอย่างมันจะเหมาะสมที่จะให้มันทำงานเป็นพจนานุกรมหากนั่นคือสิ่งที่มันพยายามเลียนแบบ

ปัญหาอื่น ๆ ที่มีtype(A) is type(B)การตรวจสอบก็คือว่าถ้าAเป็น subclass ของBมันประเมินเมื่อโปรแกรมคุณจะหวังว่ามันจะเป็นfalse trueหากวัตถุเป็นคลาสย่อยของรายการมันควรจะทำงานเหมือนรายการ: การตรวจสอบประเภทตามที่ปรากฏในคำตอบอื่น ๆ จะป้องกันไม่ให้ ( isinstanceจะใช้งานได้)


16
การพิมพ์เป็ดไม่ได้เกี่ยวกับการบอกความแตกต่าง มันเกี่ยวกับการใช้อินเทอร์เฟซทั่วไป
Justin Ethier

5
ระวัง - คู่มือสไตล์การเข้ารหัสส่วนใหญ่ไม่แนะนำให้ใช้การจัดการข้อยกเว้นเป็นส่วนหนึ่งของการควบคุมการไหลปกติของรหัสโดยปกติแล้วจะทำให้อ่านรหัสได้ยาก try... exceptเป็นทางออกที่ดีเมื่อคุณต้องการจัดการกับข้อผิดพลาด แต่ไม่ใช่เมื่อตัดสินใจเลือกพฤติกรรมตามประเภท
Rens van der Heijden

34

ในกรณีของวัตถุคุณมี:

__class__

คุณลักษณะ นี่คือตัวอย่างที่นำมาจากคอนโซล Python 3.3

>>> str = "str"
>>> str.__class__
<class 'str'>
>>> i = 2
>>> i.__class__
<class 'int'>
>>> class Test():
...     pass
...
>>> a = Test()
>>> a.__class__
<class '__main__.Test'>

ระวังว่าใน python 3.x และในคลาส New-Style (ซึ่งเป็นทางเลือกจาก Python 2.6) คลาสและประเภทได้รับการผสานและบางครั้งอาจนำไปสู่ผลลัพธ์ที่ไม่คาดคิด ด้วยเหตุผลหลักส่วนใหญ่วิธีที่ฉันชอบในการทดสอบประเภท / คลาสนี้คือฟังก์ชั่นisinstance ที่สร้างขึ้นในตัว


2
จุดของคุณในตอนท้ายมีความสำคัญมาก type (obj) เป็น Class ที่ทำงานไม่ถูกต้อง แต่ isinstance ได้ทำการหลอกลวง ฉันเข้าใจว่า isinstance เป็นที่ต้องการอยู่แล้ว แต่มันมีประโยชน์มากกว่าแค่การตรวจสอบประเภทที่ได้มาตามที่แนะนำในคำตอบที่ยอมรับ
mstbaum

__class__ส่วนใหญ่จะเป็น OK บน Python 2.x วัตถุเดียวใน Python ที่ไม่มี__class__attribute เป็น AFAIK แบบคลาสเก่า ฉันไม่เข้าใจข้อกังวลของ Python 3 ของคุณในเรื่องนี้ในทุก ๆ วัตถุมี__class__คุณลักษณะที่ชี้ไปยังคลาสที่เหมาะสม
Alan Franzoni

21

กำหนดประเภทของวัตถุ Python

กำหนดประเภทของวัตถุด้วย type

>>> obj = object()
>>> type(obj)
<class 'object'>

แม้ว่าจะได้ผลก็ตามให้หลีกเลี่ยงแอตทริบิวต์ที่ขีดเส้นใต้สองเท่าเช่น__class__- พวกเขาไม่ได้มีความหมายเชิงสาธารณะและแม้ว่าในกรณีนี้อาจจะไม่ได้ฟังก์ชั่นบิวด์อินมักจะมีพฤติกรรมที่ดีกว่า

>>> obj.__class__ # avoid this!
<class 'object'>

การตรวจสอบประเภท

มีวิธีง่ายๆในการพิจารณาว่าตัวแปรเป็นรายการพจนานุกรมหรืออย่างอื่นหรือไม่? ฉันได้รับวัตถุคืนซึ่งอาจเป็นประเภทใดประเภทหนึ่งและฉันต้องสามารถบอกความแตกต่างได้

นั่นเป็นคำถามที่แตกต่างอย่าใช้ประเภท - ใช้isinstance:

def foo(obj):
    """given a string with items separated by spaces, 
    or a list or tuple, 
    do something sensible
    """
    if isinstance(obj, str):
        obj = str.split()
    return _foo_handles_only_lists_or_tuples(obj)

กรณีนี้ครอบคลุมถึงกรณีที่ผู้ใช้ของคุณอาจทำสิ่งที่ฉลาดหรือสมเหตุสมผลโดยการทำคลาสย่อยstr- ตามหลักการของการทดแทน Liskov คุณต้องการที่จะใช้อินสแตนซ์คลาสย่อยโดยไม่ทำลายโค้ดของคุณ - และisinstanceสนับสนุนสิ่งนี้

ใช้ Abstractions

ยิ่งไปกว่านั้นคุณอาจมองหา Abstract Base Class เฉพาะจากcollectionsหรือnumbers:

from collections import Iterable
from numbers import Number

def bar(obj):
    """does something sensible with an iterable of numbers, 
    or just one number
    """
    if isinstance(obj, Number): # make it a 1-tuple
        obj = (obj,)
    if not isinstance(obj, Iterable):
        raise TypeError('obj must be either a number or iterable of numbers')
    return _bar_sensible_with_iterable(obj)

หรือเพียงแค่อย่าพิมพ์ตรวจสอบอย่างชัดเจน

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

def baz(obj):
    """given an obj, a dict (or anything with an .items method) 
    do something sensible with each key-value pair
    """
    for key, value in obj.items():
        _baz_something_sensible(key, value)

ข้อสรุป

  • ใช้typeเพื่อรับคลาสของอินสแตนซ์จริง
  • ใช้isinstanceเพื่อตรวจสอบคลาสย่อยจริงหรือ abstractions ที่ลงทะเบียนไว้อย่างชัดเจน
  • และเพียงหลีกเลี่ยงการตรวจสอบประเภทที่เหมาะสม

มีtry/ exceptตรวจสอบอย่างชัดเจนเสมอ
toonarmycaptain

สันนิษฐานว่าเป็นสิ่งที่ผู้ใช้จะทำหากพวกเขาไม่แน่ใจเกี่ยวกับประเภทที่พวกเขาจะผ่านฉันไม่ชอบความยุ่งเหยิงการใช้งานที่ถูกต้องด้วยการจัดการข้อยกเว้นถ้าฉันมีสิ่งที่ดีมากที่จะทำกับข้อยกเว้น ข้อยกเว้นที่เกิดขึ้นควรเพียงพอที่จะแจ้งให้ผู้ใช้ทราบว่าพวกเขาจำเป็นต้องแก้ไขการใช้งานของพวกเขา
Aaron Hall

13

คุณสามารถใช้หรือtype()isinstance()

>>> type([]) is list
True

ได้รับการเตือนว่าคุณสามารถอุดตันlistหรือชนิดอื่น ๆ โดยการกำหนดตัวแปรในขอบเขตปัจจุบันที่มีชื่อเดียวกัน

>>> the_d = {}
>>> t = lambda x: "aight" if type(x) is dict else "NOPE"
>>> t(the_d) 'aight'
>>> dict = "dude."
>>> t(the_d) 'NOPE'

ข้างต้นเราจะเห็นว่าdictได้รับมอบหมายให้สตริงดังนั้นการทดสอบ:

type({}) is dict

... ล้มเหลว

หากต้องการหลีกเลี่ยงสิ่งนี้และใช้type()ความระมัดระวังให้มากขึ้น:

>>> import __builtin__
>>> the_d = {}
>>> type({}) is dict
True
>>> dict =""
>>> type({}) is dict
False
>>> type({}) is __builtin__.dict
True

2
ฉันไม่แน่ใจว่าจำเป็นต้องชี้ให้เห็นว่าการแชโดว์ชื่อของชนิดข้อมูล builtin นั้นไม่ดีสำหรับกรณีนี้ คุณdictสตริงยังจะล้มเหลวจำนวนมากรหัสอื่น ๆ dict([("key1", "value1"), ("key2", "value2")])เช่น คำตอบสำหรับชนิดของปัญหาคือ"จากนั้นไม่ทำอย่างนั้น" อย่าสร้างชื่อในตัวและสร้างสิ่งที่จะทำงานได้อย่างถูกต้อง
Blckknght

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

ประเภท () ไม่ทำงานตามที่คาดไว้ใน Python 2.x สำหรับอินสแตนซ์แบบคลาสสิค
Alan Franzoni

5

ในขณะที่คำถามนั้นค่อนข้างเก่าฉันก็เจอสิ่งนี้ในขณะที่หาวิธีที่เหมาะสมด้วยตัวเองและฉันคิดว่ามันยังคงต้องการการชี้แจงอย่างน้อยสำหรับ Python 2.x (ไม่ได้ตรวจสอบ Python 3 แต่เนื่องจากปัญหาเกิดขึ้นกับคลาสคลาสสิก ซึ่งหายไปในรุ่นดังกล่าวมันอาจไม่สำคัญ)

ที่นี่ฉันพยายามตอบคำถามชื่อ: ฉันจะกำหนดประเภทของวัตถุใด ๆ ได้อย่างไร คำแนะนำอื่น ๆ เกี่ยวกับการใช้หรือไม่ใช้ isinstance นั้นใช้ได้ดีในความคิดเห็นและคำตอบมากมาย แต่ฉันไม่ได้พูดถึงข้อกังวลเหล่านั้น

ปัญหาหลักของtype()วิธีการนี้คือมันไม่ทำงานอย่างถูกต้องกับอินสแตนซ์แบบเก่า :

class One:
    pass

class Two:
    pass


o = One()
t = Two()

o_type = type(o)
t_type = type(t)

print "Are o and t instances of the same class?", o_type is t_type

การเรียกใช้ข้อมูลโค้ดนี้จะทำให้:

Are o and t instances of the same class? True

ซึ่งฉันเถียงไม่ใช่สิ่งที่คนส่วนใหญ่คาดหวัง

__class__วิธีคือใกล้ที่สุดที่จะถูกต้อง แต่มันจะไม่ทำงานในกรณีหนึ่งที่สำคัญเมื่อผ่านในวัตถุที่เป็นแบบเก่าชั้น (ไม่ได้เป็นเช่น!) ตั้งแต่วัตถุเหล่านั้นขาดแอตทริบิวต์ดังกล่าว

นี่เป็นตัวอย่างของรหัสที่เล็กที่สุดที่ฉันคิดได้ว่าเป็นไปตามคำถามที่ถูกต้องตามกฎหมายในลักษณะที่สอดคล้องกัน:

#!/usr/bin/env python
from types import ClassType
#we adopt the null object pattern in the (unlikely) case
#that __class__ is None for some strange reason
_NO_CLASS=object()
def get_object_type(obj):
    obj_type = getattr(obj, "__class__", _NO_CLASS)
    if obj_type is not _NO_CLASS:
        return obj_type
    # AFAIK the only situation where this happens is an old-style class
    obj_type = type(obj)
    if obj_type is not ClassType:
        raise ValueError("Could not determine object '{}' type.".format(obj_type))
    return obj_type

5

ระวังการใช้ isinstance

isinstance(True, bool)
True
>>> isinstance(True, int)
True

แต่พิมพ์

type(True) == bool
True
>>> type(True) == int
False

3

นอกเหนือจากคำตอบก่อนหน้านี้มันคุ้มค่าที่จะกล่าวถึงการมีอยู่ของมันcollections.abcซึ่งมีคลาสฐานนามธรรม (ABCs) หลายชั้นที่เติมเต็มการพิมพ์เป็ด

ตัวอย่างเช่นแทนที่จะตรวจสอบอย่างชัดเจนว่ามีรายการอยู่กับ:

isinstance(my_obj, list)

คุณสามารถทำได้ถ้าคุณสนใจเพียงแค่ดูว่าวัตถุที่คุณอนุญาตให้รับไอเท็มใช้หรือไม่collections.abc.Sequence:

from collections.abc import Sequence
isinstance(my_obj, Sequence) 

หากคุณสนใจอย่างเคร่งครัดในวัตถุที่ช่วยให้ได้รับการตั้งค่าและลบรายการ (คือไม่แน่นอนลำดับ) collections.abc.MutableSequenceคุณจะเลือกใช้

เบื้องต้นอื่น ๆ อีกมากมายมีการกำหนดไว้ที่นั่นMappingสำหรับวัตถุที่สามารถนำมาใช้เป็นแผนที่Iterable, Callableฯลฯ รายการเต็มรูปแบบของทั้งหมดเหล่านี้สามารถเห็นได้ในเอกสารสำหรับcollections.abc


1

โดยทั่วไปคุณสามารถแยกสตริงออกจากวัตถุด้วยชื่อคลาส

str_class = object.__class__.__name__

และใช้เพื่อการเปรียบเทียบ

if str_class == 'dict':
    # blablabla..
elif str_class == 'customclass':
    # blebleble..

1

ในกรณีที่ใช้งานได้จริงหลายอย่างแทนที่จะใช้typeหรือisinstanceคุณสามารถใช้@functools.singledispatchซึ่งใช้เพื่อกำหนดฟังก์ชั่นทั่วไป ( ฟังก์ชั่นที่ประกอบด้วยหลายฟังก์ชั่นที่ใช้การดำเนินงานเดียวกันสำหรับประเภทที่แตกต่างกัน )

กล่าวอีกนัยหนึ่งคุณต้องการใช้เมื่อคุณมีรหัสดังนี้:

def do_something(arg):
    if isinstance(arg, int):
        ... # some code specific to processing integers
    if isinstance(arg, str):
        ... # some code specific to processing strings
    if isinstance(arg, list):
        ... # some code specific to processing lists
    ...  # etc

นี่คือตัวอย่างเล็ก ๆ ของการทำงาน:

from functools import singledispatch


@singledispatch
def say_type(arg):
    raise NotImplementedError(f"I don't work with {type(arg)}")


@say_type.register
def _(arg: int):
    print(f"{arg} is an integer")


@say_type.register
def _(arg: bool):
    print(f"{arg} is a boolean")
>>> say_type(0)
0 is an integer
>>> say_type(False)
False is a boolean
>>> say_type(dict())
# long error traceback ending with:
NotImplementedError: I don't work with <class 'dict'>

นอกจากนี้เราสามารถใช้คลาสนามธรรมเพื่อครอบคลุมหลายประเภทในครั้งเดียว:

from collections.abc import Sequence


@say_type.register
def _(arg: Sequence):
    print(f"{arg} is a sequence!")
>>> say_type([0, 1, 2])
[0, 1, 2] is a sequence!
>>> say_type((1, 2, 3))
(1, 2, 3) is a sequence!

0

type()เป็นทางออกที่ดีกว่าisinstance()โดยเฉพาะสำหรับbooleans:

TrueและFalseเป็นเพียงคำหลักที่มีความหมาย1และเป็น0งูหลาม ดังนั้น,

isinstance(True, int)

และ

isinstance(False, int)

Trueทั้งสองกลับมา บูลีนทั้งสองเป็นตัวอย่างของจำนวนเต็ม type()อย่างไรก็ตามมีความฉลาดกว่า:

type(True) == int

Falseผลตอบแทน

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