पायथन में किसी वस्तु के प्रकार की तुलना कैसे करें?


163

मूल रूप से मैं यह करना चाहता हूं:

obj = 'str'
type ( obj ) == string

मैंने कोशिश की:

type ( obj ) == type ( string )

और यह काम नहीं किया।

इसके अलावा, अन्य प्रकारों के बारे में क्या? उदाहरण के लिए, मैं दोहरा नहीं सकता NoneType


यह काम करता हैtype(obj) == str
यहोशू वर्गीज

जवाबों:


241
isinstance()

आपके मामले में, isinstance("this is a string", str)वापस आ जाएगी True

आप इसे भी पढ़ना चाह सकते हैं: http://www.canonical.org/~kragen/isinstance/


4
मैं आपको (ओपी) को संदर्भित लिंक को जरूर पढ़ना चाहिए , जो इस बात का भरपूर विवरण देता है कि किसी वस्तु के प्रकार की जांच आमतौर पर एक बुरा विचार क्यों है, और आपको इसके बजाय क्या करना चाहिए।
जेफ शैनन

2
आपको बेसस्ट्र्र का उपयोग करना चाहिए, स्ट्रेट का नहीं। अन्यथा आप यूनिकोड नहीं चुनेंगे। (हालांकि 3.x के लिए मुझे लगता है कि str है basestr)
Hasen

36

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" देता है। इसके आसपास कैसे पहुंचें?
dig_123

यदि आप उपयोग करना चाहते हैं isinstanceलेकिन Noneफिर भी isinstance(obj, (MyClass, type(None)))काम करता है के लिए जाँच करें । types.NoneTypeपायथन 3 से हटा दिया गया है ताकि यह type(None)संदर्भ के रूप में पोर्टेबल न हो NoneType
संतरि पावोलैनेन

33

सबसे पहले, सभी प्रकार की तुलना से बचें। वे बहुत, बहुत कम आवश्यक हैं। कभी-कभी, वे एक फ़ंक्शन में पैरामीटर प्रकारों की जांच करने में मदद करते हैं - यहां तक ​​कि दुर्लभ भी। गलत प्रकार का डेटा एक अपवाद को बढ़ाएगा, और आपको इसकी आवश्यकता होगी।

मूल रूपांतरण फ़ंक्शन के सभी प्रकार फ़ंक्शन के बराबर मैप होंगे।

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 )

कोई नहीं, बीटीडब्ल्यू, इस प्रकार के किसी भी प्रकार की जाँच की आवश्यकता नहीं है। कोई नहीं केवल NoType का एकमात्र उदाहरण है। कोई भी वस्तु एक सिंगलटन नहीं है। बस कोई नहीं के लिए जाँच करें

variable is None

BTW, सामान्य रूप से उपरोक्त का उपयोग न करें। साधारण अपवादों और पायथन के अपने प्राकृतिक बहुरूपता का उपयोग करें।


3
यदि आप एक DSL से इनपुट्स को मान्य कर रहे हैं, तो आपको यह सब चाहिए, यहां तक ​​कि NoneType। एक पैरामीटर हो सकता है क्या एक str, unicodeया None? isinstance(x, (str, unicode, types.NoneType))के लिए जाँच करने से ज्यादा साफ है None। यदि आप आस्थगित संगणना के लिए उपकरण बना रहे हैं, या यदि आप एक लंबी या संसाधन-गहन प्रक्रिया शुरू करने वाले हैं, तो typeकुछ कस्टम सत्यापन चरण के दौरान, समय से पहले त्रुटियों को पकड़ना मूल्यवान है । यह लगभग हर वैज्ञानिक कंप्यूटिंग परियोजना का एक महत्वपूर्ण हिस्सा रहा है जिस पर मैंने कभी काम किया है। मैंने जितने भी देव परियोजनाओं को देखा है, उनमें से अधिक को इसकी आवश्यकता नहीं है।
ईली

23

अन्य प्रकारों के लिए, प्रकार मॉड्यूल की जाँच करें :

>>> 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 एक बुरा विचार है।


15

आप हमेशा 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। आप अपवादों में बहुत कुछ नहीं देखेंगे ( TypeError: 'NoneType' object is unsubscriptable- हर समय मेरे साथ होता है ..) लेकिन आपको शायद ही कभी कोड में इसे संदर्भित करने की आवश्यकता होगी।

अंत में, जैसा कि फेंगशुई बताते हैं, अजगर में प्रकार की जाँच हमेशा एक अच्छा विचार नहीं है। यह केवल मूल्य का उपयोग करने के लिए अधिक पायथोनिक है क्योंकि यह वह प्रकार है जो आप अपेक्षा करते हैं, और इसके परिणामस्वरूप होने वाले अपवादों को पकड़ (या प्रचार करने की अनुमति) दें।


1
इसके लायक क्या है, आइंस्टीन () पायथन में प्रकारों की जाँच करने का पसंदीदा तरीका है (जब आपको इसे करना हो)।
डेविड जेड

6

तुम बहुत करीब हो! stringएक मॉड्यूल है, एक प्रकार नहीं है। आप संभवतः objस्ट्रिंग के लिए ऑब्जेक्ट के प्रकार के विरुद्ध तुलना करना चाहते हैं, अर्थात् str:

type(obj) == str  # this works because str is already a type

वैकल्पिक रूप से:

type(obj) == type('')

ध्यान दें, पायथन 2 में, यदि objएक यूनिकोड प्रकार है, तो उपरोक्त में से कोई भी काम नहीं करेगा। और न ही होगा isinstance()। इस पोस्ट के बारे में जॉन की टिप्पणियों को देखें कि इसे कैसे प्राप्त करें ... मैं इसे लगभग 10 मिनट तक याद रखने की कोशिश कर रहा हूं, लेकिन मेमोरी ब्लॉक कर रहा था!


2
स्ट्रिंग और यूनिकोड दोनों को प्राप्त करने के लिए आइंस्टीन () के साथ बेसस्ट्रिंग का उपयोग करें।
जॉन फोही

5

यह इसलिए है क्योंकि आपको लिखना है

s="hello"
type(s) == type("")

प्रकार एक उदाहरण स्वीकार करता है और उसका प्रकार लौटाता है। इस मामले में आपको दो उदाहरणों के प्रकारों की तुलना करनी होगी।

यदि आपको प्रीमेप्टिव चेकिंग करने की आवश्यकता है, तो बेहतर है यदि आप टाइप की तुलना में समर्थित इंटरफ़ेस की जांच करें।

प्रकार वास्तव में आपको बहुत कुछ नहीं बताता है, इस तथ्य के अलावा कि आपका कोड एक विशिष्ट प्रकार का उदाहरण चाहता है, इस तथ्य की परवाह किए बिना कि आपके पास एक पूरी तरह से भिन्न प्रकार का एक और उदाहरण हो सकता है जो पूरी तरह से ठीक होगा क्योंकि यह एक ही इंटरफ़ेस को लागू करता है ।

उदाहरण के लिए, मान लीजिए कि आपके पास यह कोड है

def firstElement(parameter):
    return parameter[0]

अब, मान लीजिए कि आप कहते हैं: मैं चाहता हूं कि यह कोड केवल एक टपल को स्वीकार करे।

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] एक अपवाद को बढ़ाएगा यदि प्रोटोकॉल वैसे भी संतुष्ट नहीं है ... निश्चित रूप से जब तक आप साइड इफेक्ट्स को रोकने या कॉल से उबरने से रोकना चाहते हैं, जिसे आप असफल होने से पहले लागू कर सकते हैं। (मूर्ख) उदाहरण, बस बात बनाने के लिए:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

इस स्थिति में, आपका कोड सिस्टम () कॉल को चलाने से पहले एक अपवाद बढ़ाएगा। इंटरफ़ेस जांच के बिना, आपने फ़ाइल को हटा दिया होगा, और फिर अपवाद को उठाया।


इंटरफेस के लिए जाँच करने के लिए वास्तविक पसंदीदा तरीका इंगित करने के लिए धन्यवाद। यहाँ के कई उत्तर इसका उल्लेख करते हैं, लेकिन कुछ इसके उदाहरण देते हैं कि इसके बजाय क्या अच्छा है। यह अभी भी सीधे मेरे व्यक्तिगत प्रश्न का उत्तर नहीं देता है (मैं तार की एक सूची को अलग करने की कोशिश कर रहा हूं, जिसमें स्ट्रिंग से कई, सार्थक आइटम होते हैं, जिसमें कई, सार्थक आइटम नहीं होते हैं। धन्यवाद!
निक

5

स्ट्रिंग के बजाय str का उपयोग करें

type ( obj ) == str

व्याख्या

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>

4

मैं उपयोग करता हूं type(x) == type(y)

उदाहरण के लिए, अगर मैं कुछ जाँचना चाहता हूँ तो यह एक सरणी है:

type( x ) == type( [] )

स्ट्रिंग जांच:

type( x ) == type( '' ) or type( x ) == type( u'' )

यदि आप किसी के खिलाफ जांच नहीं करना चाहते हैं, तो उपयोग है

x is None

है ना? यह सामान्य रूप से बुरा विचार क्यों है? यह स्ट्रिंग्स के लिए केवल एक बुरा विचार है (पूर्व 3.0 के लिए) क्योंकि स्ट्रिंग्स और यूनिकोड दो प्रकार के होते हैं। सरणियों के लिए, यह एक अच्छा विचार imho है।
hasen

@ हसीन: यह कुल मिलाकर एक बुरा विचार है। क्या होगा यदि मैं अपने स्वयं के प्रकार को परिभाषित करता हूं जो एक सरणी की तरह व्यवहार करता है, लेकिन कहते हैं, डेटाबेस से मान प्राप्त करते हैं? आपका कोड बिना किसी कारण के मेरे प्रकार के साथ विफल हो जाएगा।
nosklo

@hasen: voltronw
nosklo

1
ठीक है, प्रकार की जाँच करने में पूरा कारण (मेरे लिए कम से कम) ठीक उसी तरह है क्योंकि मैं अन्य प्रकारों की तुलना में भिन्न प्रकारों से निपटना चाहता हूँ (जिसमें प्रकार जो सरणियों का अनुकरण करते हैं)।
अपराह्न

2
तुम गलत हो। मैं आपको एक ठोस उदाहरण दूंगा: django में एक टेम्प्लेट रेंडरिंग शॉर्टकट है जो स्ट्रिंग या सरणी के एक सरणी को स्वीकार कर सकता है। अब, दोनों तार और सरणियाँ (सूचियाँ) चलने योग्य हैं, लेकिन इस मामले में, कार्यों को उनके बीच अंतर करने की आवश्यकता है।
hasen


2

टाइप कुछ वर्गों पर काम नहीं करता है। यदि आप वस्तु के प्रकार के बारे में सुनिश्चित नहीं हैं __class__, तो विधि का उपयोग करें:

>>>obj = 'a string'
>>>obj.__class__ == str
True

इस लेख को भी देखें - http://www.siafoo.net/article/56


2

प्रकार प्राप्त करने के लिए, __class__सदस्य का उपयोग करें , जैसे किunknown_thing.__class__

बत्तख-टाइप की बात यहाँ बेकार है क्योंकि यह एक अच्छे सवाल का जवाब नहीं देता है। मेरे एप्लिकेशन कोड में मुझे कभी किसी चीज़ के प्रकार को जानने की आवश्यकता नहीं है, लेकिन किसी वस्तु के प्रकार को सीखने का एक तरीका होना अभी भी उपयोगी है। कभी-कभी मुझे इकाई परीक्षण को मान्य करने के लिए वास्तविक वर्ग प्राप्त करने की आवश्यकता होती है। बतख टाइपिंग वहाँ रास्ते में हो जाती है क्योंकि सभी संभव वस्तुओं में एक ही एपीआई है, लेकिन केवल एक ही सही है। इसके अलावा, कभी-कभी मैं किसी और के कोड को बनाए रख रहा हूं, और मुझे नहीं पता कि मुझे किस तरह की वस्तु दी गई है। यह पायथन जैसी गतिशील रूप से टाइप की गई भाषाओं के साथ मेरी सबसे बड़ी समस्या है। संस्करण 1 विकसित करने के लिए बहुत आसान और त्वरित है। संस्करण 2 बन्स में एक दर्द है, खासकर यदि आपने संस्करण 1 नहीं लिखा है। इसलिए कभी-कभी, जब मैं एक फ़ंक्शन के साथ काम कर रहा हूं जो मैंने नहीं लिखा है, तो मुझे एक पैरामीटर के प्रकार को जानने की आवश्यकता है,

यहीं __class__पैरामीटर काम आता है। वह (जहां तक ​​मैं बता सकता हूं) किसी वस्तु के प्रकार को प्राप्त करने का सबसे अच्छा तरीका (शायद एकमात्र तरीका) है।


2

का उपयोग करें 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 

तो मैं एक चर ( yइस मामले में) को उस प्रकार के ऑब्जेक्ट के साथ जो आप जांचना चाहते हैं (जैसे, type(np.array())), तब उपयोग कर की अनुशंसा करते हैं isinstance


0

आप चेक स्तर के लिए कक्षाओं की तुलना कर सकते हैं।

#!/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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.