पायथन में isinstance()
और के बीच अंतर type()
?
टाइप-चेकिंग के साथ
isinstance(obj, Base)
उपवर्गों और कई संभावित ठिकानों के उदाहरणों के लिए अनुमति देता है:
isinstance(obj, (Base1, Base2))
टाइप-चेकिंग के साथ
type(obj) is Base
केवल संदर्भित प्रकार का समर्थन करता है।
एक विचार के रूप में, is
संभावना से अधिक उपयुक्त है
type(obj) == Base
क्योंकि कक्षाएं एकल हैं।
टाइप-चेकिंग से बचें - पॉलिमॉर्फिज्म (डक-टाइपिंग) का उपयोग करें
पायथन में, आमतौर पर आप अपने तर्क के लिए किसी भी प्रकार की अनुमति देना चाहते हैं, इसे अपेक्षा के अनुसार व्यवहार करें, और यदि ऑब्जेक्ट अपेक्षा के अनुरूप व्यवहार नहीं करता है, तो यह एक उपयुक्त त्रुटि को बढ़ाएगा। इसे बहुरूपता के रूप में जाना जाता है, जिसे डक-टाइपिंग भी कहा जाता है।
def function_of_duck(duck):
duck.quack()
duck.swim()
यदि उपरोक्त कोड काम करता है, तो हम मान सकते हैं कि हमारा तर्क एक बतख है। इस प्रकार हम अन्य चीजों में पास हो सकते हैं, बतख के वास्तविक उप-प्रकार हैं:
function_of_duck(mallard)
या वह एक बतख की तरह काम करता है:
function_of_duck(object_that_quacks_and_swims_like_a_duck)
और हमारा कोड अभी भी काम करता है।
हालांकि, कुछ ऐसे मामले हैं जहां स्पष्ट रूप से टाइप-चेक करना वांछनीय है। शायद आपके पास विभिन्न वस्तु प्रकारों के साथ समझदार चीजें हैं। उदाहरण के लिए, पंडों डेटाफ़ॉर्म ऑब्जेक्ट का निर्माण डाइक या रिकॉर्ड से किया जा सकता है । ऐसे मामले में, आपके कोड को यह जानना होगा कि उसे किस प्रकार का तर्क मिल रहा है ताकि वह उसे ठीक से संभाल सके।
तो, सवाल का जवाब देने के लिए:
पायथन में isinstance()
और के बीच अंतर type()
?
मुझे अंतर प्रदर्शित करने की अनुमति दें:
type
यदि आपके फ़ंक्शन को एक निश्चित प्रकार का तर्क (निर्माणकर्ताओं के लिए एक सामान्य उपयोग-मामला) मिलता है, तो आपको एक निश्चित व्यवहार सुनिश्चित करने की आवश्यकता है। यदि आप इस प्रकार की जाँच करते हैं:
def foo(data):
'''accepts a dict to construct something, string support in future'''
if type(data) is not dict:
# we're only going to test for dicts for now
raise ValueError('only dicts are supported for now')
यदि हम एक ऐसे श्रुतलेख में उत्तीर्ण होने का प्रयास करते हैं जो dict
(जैसा कि हमें सक्षम होना चाहिए, यदि हम लिस्कोव प्रतिस्थापन के सिद्धांत का पालन करने के लिए हमारे कोड की अपेक्षा कर रहे हैं, तो उप-प्रकारों को प्रतिस्थापित किया जा सकता है) हमारा कोड टूट जाता है!
from collections import OrderedDict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
कोई त्रुटि उठाता है!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in foo
ValueError: argument must be a dict
isinstance
लेकिन अगर हम उपयोग करते हैं isinstance
, तो हम लिस्कोव प्रतिस्थापन का समर्थन कर सकते हैं! "
def foo(a_dict):
if not isinstance(a_dict, dict):
raise ValueError('argument must be a dict')
return a_dict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
रिटर्न OrderedDict([('foo', 'bar'), ('fizz', 'buzz')])
सार आधार वर्ग
वास्तव में, हम और भी बेहतर कर सकते हैं। collections
विभिन्न प्रकार के लिए न्यूनतम प्रोटोकॉल लागू करने वाले सार बेस कक्षाएं प्रदान करता है। हमारे मामले में, यदि हम केवल Mapping
प्रोटोकॉल की उम्मीद करते हैं, तो हम निम्नलिखित कर सकते हैं, और हमारा कोड और भी अधिक लचीला हो जाता है:
from collections import Mapping
def foo(a_dict):
if not isinstance(a_dict, Mapping):
raise ValueError('argument must be a dict')
return a_dict
टिप्पणी करने के लिए प्रतिक्रिया:
यह ध्यान दिया जाना चाहिए कि प्रकार का उपयोग करके कई वर्गों के खिलाफ जांच करने के लिए किया जा सकता है type(obj) in (A, B, C)
हां, आप प्रकारों की समानता के लिए परीक्षण कर सकते हैं, लेकिन उपरोक्त के बजाय, नियंत्रण प्रवाह के लिए कई आधारों का उपयोग करें, जब तक कि आप विशेष रूप से केवल उन प्रकारों की अनुमति न दें:
isinstance(obj, (A, B, C))
फिर से, अंतर यह है कि isinstance
उपवर्गों का समर्थन करता है जिन्हें माता-पिता के लिए अन्यथा कार्यक्रम को तोड़ने के बिना प्रतिस्थापित किया जा सकता है, एक संपत्ति जिसे लिस्कोव प्रतिस्थापन कहा जाता है।
हालांकि, इससे भी बेहतर, अपनी निर्भरता को उल्टा करें और विशिष्ट प्रकारों की जांच बिल्कुल न करें।
निष्कर्ष
इसलिए जब से हम उपवर्गों को प्रतिस्थापित करने का समर्थन करना चाहते हैं, ज्यादातर मामलों में, हम टाइप-चेकिंग से बचना चाहते हैं type
और इसके साथ टाइप-चेकिंग पसंद करते हैं isinstance
- जब तक कि आपको वास्तव में किसी उदाहरण की सटीक कक्षा जानने की आवश्यकता न हो।
str
औरunicode
(जहां आप सिर्फ जांचbasestring
कर सकते हैं), तो आप कई प्रकारों के खिलाफ जाँच के लिए टपल का उपयोग कर सकते हैं। यह जाँचने के लिए किsomething
क्या उपयोग हैint
या नहीं ।str
isinstance(something, (int, str))