โดยทั่วไปฉันต้องการทำสิ่งนี้:
obj = 'str'
type ( obj ) == string
ฉันเหนื่อย:
type ( obj ) == type ( string )
และมันไม่ทำงาน
แล้วประเภทอื่น ๆ ล่ะ? NoneType
ตัวอย่างเช่นผมไม่สามารถทำซ้ำ
โดยทั่วไปฉันต้องการทำสิ่งนี้:
obj = 'str'
type ( obj ) == string
ฉันเหนื่อย:
type ( obj ) == type ( string )
และมันไม่ทำงาน
แล้วประเภทอื่น ๆ ล่ะ? NoneType
ตัวอย่างเช่นผมไม่สามารถทำซ้ำ
คำตอบ:
isinstance()
ในกรณีของคุณจะกลับมาisinstance("this is a string", str)
True
คุณอาจต้องการอ่านสิ่งนี้: http://www.canonical.org/~kragen/isinstance/
isinstance
การทำงาน:
if isinstance(obj, MyClass): do_foo(obj)
แต่โปรดจำไว้ว่า: ถ้ามันดูเหมือนเป็ดและถ้ามันดูเหมือนเป็ดมันก็เป็นเป็ด
แก้ไข: สำหรับประเภทไม่มีคุณสามารถทำได้:
if obj is None: obj = MyClass()
def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True)
ส่งกลับค่า "1" แทน "Nope" ทำอย่างไรจึงจะได้สิ่งนี้
isinstance
แต่ตรวจสอบNone
แล้วยังใช้isinstance(obj, (MyClass, type(None)))
งานได้ types.NoneType
ถูกลบออกจาก Python 3 แล้วดังนั้นจึงไม่สามารถพกพาtype(None)
ไปอ้างอิงNoneType
ได้
ก่อนอื่นให้หลีกเลี่ยงการเปรียบเทียบทุกประเภท พวกมันจำเป็นมาก ๆ บางครั้งพวกเขาช่วยตรวจสอบประเภทพารามิเตอร์ในฟังก์ชั่น - แม้จะหายาก ข้อมูลประเภทที่ไม่ถูกต้องจะเพิ่มข้อยกเว้นและนั่นคือทั้งหมดที่คุณต้องการ
ฟังก์ชั่นการแปลงพื้นฐานทั้งหมดจะแมปเท่ากับฟังก์ชั่นประเภท
type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex
มีอีกหลายกรณี
isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )
ไม่มี BTW ไม่ต้องการการตรวจสอบประเภทนี้อีกเลย None เป็นเพียงตัวอย่างของ NoneType วัตถุไม่มีเป็นแบบซิงเกิล เพียงตรวจสอบไม่มี
variable is None
BTW ห้ามใช้สิ่งเหล่านี้โดยทั่วไป ใช้ข้อยกเว้นสามัญและความแตกต่างตามธรรมชาติของไพ ธ อน
NoneType
คุณต้องการทั้งหมดนี้แม้ เกิดอะไรขึ้นถ้าพารามิเตอร์สามารถเป็นstr
, unicode
หรือNone
? มากสะอาดกว่าการตรวจสอบisinstance(x, (str, unicode, types.NoneType))
None
หากคุณกำลังสร้างเครื่องมือสำหรับการคำนวณที่เลื่อนออกไปหรือหากคุณกำลังจะเปิดตัวกระบวนการที่ใช้เวลานานหรือใช้ทรัพยากรมากมันมีประโยชน์ที่จะตรวจจับtype
ข้อผิดพลาดล่วงหน้าในระหว่างขั้นตอนการตรวจสอบความถูกต้องที่กำหนดเอง นี่เป็นส่วนสำคัญของโครงการคำนวณทางวิทยาศาสตร์เกือบทุกโครงการที่ฉันเคยทำ จากโครงการพัฒนาทั้งหมดที่ฉันเคยเห็นมีความต้องการมากกว่านี้
สำหรับประเภทอื่น ๆ ตรวจสอบโมดูลประเภท :
>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True
PS Typechecking เป็นความคิดที่ไม่ดี
คุณสามารถใช้type(x) == type(y)
เคล็ดลับซึ่งy
เป็นประเภทที่รู้จักกันเสมอ
# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)
บ่อยครั้งที่มีวิธีที่ดีกว่าในการทำเช่นนั้นโดยเฉพาะกับงูใหญ่ตัวล่าสุด แต่ถ้าคุณต้องการจำเพียงสิ่งเดียวคุณก็สามารถจำได้
ในกรณีนี้วิธีที่ดีกว่าคือ:
# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None
หมายเหตุกรณีที่ผ่านมา: มีเพียงหนึ่งตัวอย่างของในหลามและนั่นคือNoneType
None
คุณจะเห็น NoneType เป็นจำนวนมากยกเว้น ( TypeError: 'NoneType' object is unsubscriptable
- เกิดขึ้นกับฉันตลอดเวลา .. ) แต่คุณแทบจะไม่จำเป็นต้องอ้างถึงในรหัส
ในที่สุดเมื่อ fengshaun ชี้ให้เห็นการพิมพ์แบบหลามไม่ใช่ความคิดที่ดีเสมอไป มันเป็นแบบ pythonic มากกว่าเพียงแค่ใช้ค่าราวกับเป็นประเภทที่คุณคาดหวังและจับข้อยกเว้น (หรืออนุญาตให้เผยแพร่) ที่เป็นผลมาจากมัน
คุณสนิทมาก! string
เป็นโมดูลไม่ใช่ประเภท คุณอาจต้องการเปรียบเทียบประเภทของobj
กับวัตถุประเภทสำหรับสตริงคือstr
:
type(obj) == str # this works because str is already a type
อีกวิธีหนึ่งคือ:
type(obj) == type('')
หมายเหตุใน Python 2 ถ้าobj
เป็น unicode จะไม่สามารถใช้งานได้ isinstance()
หรือจะ ดูความเห็นของจอห์นต่อโพสต์นี้เพื่อดูว่าต้องทำอย่างไรต่อไปนี้ ... ฉันพยายามจะจำมันได้ประมาณ 10 นาทีแล้ว แต่มีบล็อกหน่วยความจำอยู่!
เป็นเพราะคุณต้องเขียน
s="hello"
type(s) == type("")
type ยอมรับอินสแตนซ์และคืนค่าประเภท ในกรณีนี้คุณต้องเปรียบเทียบสองประเภท
หากคุณจำเป็นต้องทำการตรวจสอบแบบ preemptive จะเป็นการดีกว่าถ้าคุณตรวจสอบหาส่วนต่อประสานที่รองรับได้
ประเภทไม่ได้บอกอะไรคุณมากนักนอกจากความจริงที่ว่าโค้ดของคุณต้องการอินสแตนซ์ของประเภทเฉพาะโดยไม่คำนึงถึงความจริงที่ว่าคุณสามารถมีอินสแตนซ์อื่นที่มีประเภทแตกต่างกันโดยสิ้นเชิง .
ตัวอย่างเช่นสมมติว่าคุณมีรหัสนี้
def firstElement(parameter):
return parameter[0]
ตอนนี้สมมติว่าคุณพูดว่า: ฉันต้องการให้รหัสนี้ยอมรับ tuple เท่านั้น
import types
def firstElement(parameter):
if type(parameter) != types.TupleType:
raise TypeError("function accepts only a tuple")
return parameter[0]
นี่คือการลดการนำมาใช้ซ้ำของกิจวัตรนี้ มันจะไม่ทำงานถ้าคุณผ่านรายการหรือสตริงหรือ numpy.array สิ่งที่ดีกว่าจะเป็น
def firstElement(parameter):
if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
raise TypeError("interface violation")
return parameter[0]
แต่ไม่มีประโยชน์ในการทำเช่นนั้น: พารามิเตอร์ [0] จะเพิ่มข้อยกเว้นหากโปรโตคอลไม่เป็นที่พอใจอย่างไรก็ตามแน่นอนว่าถ้าคุณต้องการป้องกันผลข้างเคียงหรือไม่ต้องกู้จากการโทรที่คุณสามารถเรียกใช้ก่อนที่จะล้มเหลว ตัวอย่าง (Stupid) เพียงเพื่อให้ประเด็น:
def firstElement(parameter):
if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
raise TypeError("interface violation")
os.system("rm file")
return parameter[0]
ในกรณีนี้รหัสของคุณจะยกข้อยกเว้นก่อนเรียกใช้ระบบ () โทร หากไม่มีการตรวจสอบส่วนต่อประสานคุณจะลบไฟล์ออกแล้วยกข้อยกเว้น
ใช้ str แทนสตริง
type ( obj ) == str
คำอธิบาย
>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>
ฉันใช้ type(x) == type(y)
ตัวอย่างเช่นถ้าฉันต้องการตรวจสอบบางอย่างเป็นอาร์เรย์:
type( x ) == type( [] )
ตรวจสอบสตริง:
type( x ) == type( '' ) or type( x ) == type( u'' )
หากคุณต้องการตรวจสอบกับไม่มีใช้เป็น
x is None
ฉันคิดว่าสิ่งนี้ควรทำ
if isinstance(obj, str)
ประเภทใช้ไม่ได้กับบางคลาส หากคุณไม่แน่ใจเกี่ยวกับประเภทของวัตถุให้ใช้__class__
วิธีการดังนี้:
>>>obj = 'a string'
>>>obj.__class__ == str
True
ดูบทความนี้ - http://www.siafoo.net/article/56
ในการรับชนิดใช้__class__
สมาชิกเช่นเดียวกับในunknown_thing.__class__
พูดถึงการพิมพ์เป็ดไม่มีประโยชน์ที่นี่เพราะมันไม่ได้ตอบคำถามที่ดีอย่างสมบูรณ์ ในรหัสแอปพลิเคชันของฉันฉันไม่จำเป็นต้องรู้ประเภทของสิ่งใด แต่ก็ยังมีประโยชน์ในการเรียนรู้ประเภทของวัตถุ บางครั้งฉันต้องได้รับชั้นเรียนจริงเพื่อตรวจสอบการทดสอบหน่วย การพิมพ์เป็ดเข้าทางเพราะวัตถุที่เป็นไปได้ทั้งหมดมี API เดียวกัน แต่มีเพียงหนึ่งอย่างถูกต้อง นอกจากนี้บางครั้งฉันก็รักษารหัสของคนอื่นและฉันก็ไม่รู้เหมือนกันว่าวัตถุชนิดใดที่ฉันเคยผ่าน นี่คือปัญหาที่ใหญ่ที่สุดของฉันกับภาษาที่พิมพ์แบบไดนามิกเช่น Python เวอร์ชัน 1 นั้นง่ายและรวดเร็วในการพัฒนา เวอร์ชัน 2 เป็นความเจ็บปวดในขนมปังโดยเฉพาะอย่างยิ่งถ้าคุณไม่ได้เขียนเวอร์ชัน 1 ดังนั้นบางครั้งเมื่อฉันทำงานกับฟังก์ชั่นที่ฉันไม่ได้เขียนฉันจำเป็นต้องรู้ประเภทของพารามิเตอร์
นั่นคือสิ่งที่__class__
พารามิเตอร์มีประโยชน์ นั่น (เท่าที่ฉันสามารถบอกได้) เป็นวิธีที่ดีที่สุด (อาจเป็นวิธีเดียว) ในการรับชนิดของวัตถุ
isinstance(object, type)
ใช้ ดังกล่าวข้างต้นนี้ใช้งานง่ายถ้าคุณรู้ว่าถูกต้องtype
เช่น
isinstance('dog', str) ## gives bool True
แต่สำหรับวัตถุที่ลึกลับกว่านี้อาจเป็นเรื่องยากที่จะใช้ ตัวอย่างเช่น:
import numpy as np
a = np.array([1,2,3])
isinstance(a,np.array) ## breaks
แต่คุณสามารถทำเคล็ดลับนี้:
y = type(np.array([1]))
isinstance(a,y) ## gives bool True
ดังนั้นผมจึงขอแนะนำให้ instantiating ตัวแปร ( y
ในกรณีนี้) กับชนิดของวัตถุที่คุณต้องการตรวจสอบ (เช่นtype(np.array())
) isinstance
แล้วใช้
คุณสามารถเปรียบเทียบชั้นเรียนสำหรับระดับการตรวจสอบ
#!/usr/bin/env python
#coding:utf8
class A(object):
def t(self):
print 'A'
def r(self):
print 'rA',
self.t()
class B(A):
def t(self):
print 'B'
class C(A):
def t(self):
print 'C'
class D(B, C):
def t(self):
print 'D',
super(D, self).t()
class E(C, B):
pass
d = D()
d.t()
d.r()
e = E()
e.t()
e.r()
print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ < E, #False
print e.__class__ <= E #True
type(obj) == str