यह जांचने का सबसे अच्छा तरीका है कि क्या दी गई वस्तु किसी प्रकार की है? कैसे के बारे में जाँच है कि क्या वस्तु एक प्रकार से विरासत में मिली है?
मान लीजिए कि मेरे पास एक वस्तु है o
। मैं कैसे जांच करूं कि क्या यह एक है str
?
यह जांचने का सबसे अच्छा तरीका है कि क्या दी गई वस्तु किसी प्रकार की है? कैसे के बारे में जाँच है कि क्या वस्तु एक प्रकार से विरासत में मिली है?
मान लीजिए कि मेरे पास एक वस्तु है o
। मैं कैसे जांच करूं कि क्या यह एक है str
?
जवाबों:
यह जाँचने के लिए कि o
क्या कोई उदाहरण है str
या किसी उपवर्ग का str
उपयोग कर रहा है, आइंस्टीन का उपयोग करें (यह "विहित" तरीका होगा):
if isinstance(o, str):
यह जाँचने के लिए कि क्या प्रकार o
ठीक है str
(उपवर्गों को बाहर करें):
if type(o) is str:
निम्नलिखित भी काम करता है, और कुछ मामलों में उपयोगी हो सकता है:
if issubclass(type(o), str):
देखें निर्मित कार्य प्रासंगिक जानकारी के लिए अजगर लाइब्रेरी संदर्भ में।
एक और ध्यान दें: इस मामले में, यदि आप पायथन 2 का उपयोग कर रहे हैं, तो आप वास्तव में उपयोग करना चाहते हैं:
if isinstance(o, basestring):
क्योंकि यह भी यूनिकोड तार पकड़ेगा ( unicode
का एक उपवर्ग नहीं है str
, दोनों str
और unicode
के उपवर्गों हैं basestring
)। ध्यान दें कि basestring
अब पायथन 3 में मौजूद नहीं है, जहां स्ट्रिंग्स का सख्त अलगाव है (str
) और बाइनरी डेटा ( bytes
) ।
वैकल्पिक रूप से, isinstance
कक्षाओं के एक समूह को स्वीकार करता है। True
यदि o
किसी के किसी उपवर्ग का उदाहरण है तो यह वापस आ जाएगा (str, unicode)
:
if isinstance(o, (str, unicode)):
type(a) is Object
ऐसा नहीं है तो यह भी सच है isinstance(a, Object)
। हालांकि, अगर type(a) is SubClassOfObject
, फिर type(a) is Object == False
, लेकिन isinstance(a, Object) == True
। सही?
a is b
अर्थ है ए और बी, एक ही बात है, अर्थात स्मृति में एक ही इकाई के संदर्भ में। तो a
और b
साथ के रूप में, ठीक उसी वर्ग, नहीं उपवर्गों होना चाहिए था isinstance()
। उदाहरण के लिए देखें stackoverflow.com/a/133024/1072212
किसी ऑब्जेक्ट के प्रकार की जांच करने का सबसे पायथोनिक तरीका है ... इसे जांचना नहीं।
चूंकि पायथन डक टंकण को प्रोत्साहित करता है , आपको बस try...except
वस्तु के तरीकों का उपयोग करना चाहिए जिस तरह से आप उनका उपयोग करना चाहते हैं। इसलिए यदि आपका फ़ंक्शन एक लिखने योग्य फ़ाइल ऑब्जेक्ट की तलाश कर रहा है, तो यह जांचें कि यह एक उपवर्ग है file
, बस इसकी .write()
विधि का उपयोग करने का प्रयास करें !
बेशक, कभी-कभी ये अच्छे अमूर्त टूट जाते हैं और isinstance(obj, cls)
आपकी आवश्यकता होती है। लेकिन संयम से उपयोग करें।
if hasattr(ob, "write") and callable(ob.write):
या कुछ func = getattr(ob, "write", None)
if callable(func): ...
hasattr
केवल एक गुण को दर्शाता है
isinstance(o, str)
वापस आ जाएगा True
यदि o
एक str
या एक प्रकार का है जो विरासत में मिला है str
।
type(o) is str
वापस आ जाएगा True
और अगर केवल o
एक str है। यह वापस आ जाएगी False
, तो o
एक प्रकार है कि से विरासत में मिली की है str
।
isinstance
और type(var) == type('')
स्पष्ट नहीं है।
सवाल पूछे जाने और जवाब देने के बाद, पायथन में टाइप संकेत जोड़े गए । पाइथन में टाइप संकेत, प्रकारों की जाँच करने की अनुमति देते हैं लेकिन सांख्यिकीय रूप से टाइप की गई भाषाओं से बहुत अलग तरीके से। अजगर में टाइप करें संकेत कार्यों के साथ जुड़े क्रम सुलभ डेटा के रूप में कार्य करता है के साथ बहस की उम्मीद प्रकार सहयोगी है और इस अनुमति देता है प्रकार की जाँच की जानी करने के लिए। प्रकार संकेत वाक्यविन्यास का उदाहरण:
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
अपने पैकेज मैनेजर से । मुझे नहीं लगता कि यह सीपीथॉन के साथ आता है, लेकिन लगता है कि "आधिकारिकता" का कुछ स्तर है।)
इस तरह से जाँच करना, सांख्यिकीय रूप से संकलित भाषाओं में टाइप जाँच से अलग है। क्योंकि पायथन में प्रकार गतिशील होते हैं, टाइप चेकिंग रनटाइम पर की जानी चाहिए, जो एक लागत लगाता है - यहां तक कि सही कार्यक्रमों पर - अगर हम जोर देते हैं कि यह हर मौके पर होता है। स्पष्ट प्रकार की जांच आवश्यकता से अधिक प्रतिबंधात्मक हो सकती है और अनावश्यक त्रुटियों का कारण बन सकती है (जैसे कि तर्क वास्तव में सटीक होना चाहिएlist
प्रकार या क्या यह पर्याप्त रूप से पर्याप्त है?)।
स्पष्ट प्रकार की जाँच का नकारात्मक पक्ष यह है कि यह पहले की त्रुटियों को पकड़ सकता है और बतख टाइपिंग की तुलना में स्पष्ट त्रुटि संदेश दे सकता है। एक बतख प्रकार की सटीक आवश्यकताओं को केवल बाहरी दस्तावेज के साथ व्यक्त किया जा सकता है (उम्मीद है कि यह पूरी तरह से और सटीक है) और असंगत प्रकारों से त्रुटियां दूर हो सकती हैं जहां से वे उत्पन्न होते हैं।
पायथन के प्रकार संकेत एक ऐसे समझौते की पेशकश करने के लिए हैं जहां प्रकार निर्दिष्ट किए जा सकते हैं और जांचे जा सकते हैं लेकिन सामान्य कोड निष्पादन के दौरान कोई अतिरिक्त लागत नहीं है।
typing
पैकेज ऑफर प्रकार चर उस प्रकार संकेत में इस्तेमाल किया जा सकता विशेष प्रकार की आवश्यकता के बिना आवश्यक व्यवहार व्यक्त करते हैं। उदाहरण के लिए, इसमें उन व्यवहारों के साथ किसी भी प्रकार की आवश्यकता को निर्दिष्ट करने के लिए चर Iterable
और Callable
संकेत जैसे चर शामिल हैं।
जबकि प्रकार के संकेत प्रकारों की जांच करने के लिए सबसे Pythonic तरीका है, यह अक्सर और भी अधिक Pythonic है कि सभी प्रकार की जाँच न करें और बतख टाइपिंग पर निर्भर रहें। टाइप संकेत अपेक्षाकृत नए हैं और जूरी अभी भी बाहर है जब वे सबसे पायथोनिक समाधान हैं। एक अपेक्षाकृत विवादास्पद लेकिन बहुत ही सामान्य तुलना: टाइप संकेत दस्तावेज़ीकरण का एक रूप प्रदान करते हैं जिसे लागू किया जा सकता है, कोड को पहले उत्पन्न करने की अनुमति देता है और त्रुटियों को समझने में आसान है, उन त्रुटियों को पकड़ सकता है जो बतख टाइपिंग नहीं कर सकते हैं, और सांख्यिकीय रूप से जांच की जा सकती है (एक असामान्य रूप में) समझ लेकिन यह अभी भी रनटाइम के बाहर है)। दूसरी ओर, बतख टाइपिंग लंबे समय से पाइथोनिक तरीका रहा है, स्थैतिक टाइपिंग के संज्ञानात्मक ओवरहेड को लागू नहीं करता है, कम क्रिया है, और सभी व्यवहार्य प्रकारों को स्वीकार करेगा और फिर कुछ।
mypy
एक पायथन मॉड्यूल है जो importlib
उस डेटा का उपयोग करने के लिए उपयोग करता है। क्या यह "स्टैटिक टाइप चेकिंग" एक दार्शनिक प्रश्न है, लेकिन यह सामान्य भाषा दुभाषिया और आयात मशीनरी के शामिल होने के बाद से सबसे ज्यादा क्या उम्मीद करता है, उससे अलग है।
यहां एक उदाहरण दिया गया है कि डक टाइपिंग यह जानने के बिना कि यह खतरनाक कब है? उदाहरण के लिए: यहां पायथन कोड है (संभवतः उचित इंडेंटिंग को छोड़ना), ध्यान दें कि यह स्थिति आइंस्टीन और आइसबक्लासोफ कार्यों का ध्यान रखने से बचने योग्य है, यह सुनिश्चित करने के लिए कि जब आपको वास्तव में बतख की आवश्यकता होती है, तो आपको बम नहीं मिलता है।
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()
class EvilDuck(Duck)
और ओवरराइड टॉक बना सकते हैं ()। या अधिक संभावना है, class ChineseCancerDuck(Duck)
एक बुरा साइड इफेक्ट के साथ जो वर्षों बाद तक दिखाई नहीं देता है। आप अपने बच्चे की देखरेख करना बेहतर समझेंगे (और उसके खिलौनों का पूरी तरह से परीक्षण कर सकते हैं :)
__file__
विशेषता को ओवरराइड करके (आमतौर पर फ़ाइल की तरह वस्तुओं की पहचान करने के लिए) कुछ और मतलब करने के लिए पायथन कोड का एक बहुत बड़ा हिस्सा बना सकते हैं ।
isinstance(o, str)
मुझे लगता है कि पायथन जैसी गतिशील भाषा का उपयोग करने के बारे में अच्छी बात यह है कि वास्तव में आपको ऐसा कुछ नहीं देखना चाहिए।
मैं सिर्फ आपकी वस्तु पर आवश्यक तरीकों को कॉल करूंगा और एक को पकड़ सकता हूं AttributeError
। बाद में इस पर आप विभिन्न तरीकों से काम करने के लिए अन्य (प्रतीत होता है असंबंधित) वस्तुओं के साथ अपने तरीकों को कॉल करने की अनुमति देंगे, जैसे कि परीक्षण के लिए एक वस्तु का मज़ाक उड़ाना।
मैंने वेब से डेटा प्राप्त करते समय इसका बहुत उपयोग किया है, urllib2.urlopen()
जिसके साथ ऑब्जेक्ट जैसी फ़ाइल लौटाता है । यह बदले में एक फ़ाइल से पढ़ी जाने वाली लगभग किसी भी विधि से पारित किया जा सकता है, क्योंकि यह उसी read()
पद्धति को वास्तविक फ़ाइल के रूप में लागू करता है ।
लेकिन मुझे यकीन है कि उपयोग करने के लिए एक समय और स्थान है isinstance()
, अन्यथा यह संभवतः नहीं होगा :)
अधिक जटिल प्रकार के सत्यापन के लिए, मुझे अजगर प्रकार संकेत एनोटेशन के आधार पर टाइप करने के दृष्टिकोण को पसंद करना है :
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)
आप एक प्रकार के __name__ का उपयोग करके एक चर के प्रकार की जांच कर सकते हैं।
उदाहरण के लिए:
>>> 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'
ह्यूगो को:
आप शायद के list
बजाय मतलब हैarray
, लेकिन यह पूरी समस्या के प्रकार की जाँच के साथ इंगित करता है - आप नहीं जानना चाहते हैं कि क्या प्रश्न में वस्तु एक सूची है, तो आप जानना चाहते हैं कि क्या यह किसी प्रकार का अनुक्रम है या यदि यह एक एकल वस्तु है। इसलिए इसे एक सीक्वेंस की तरह इस्तेमाल करने की कोशिश करें।
मान लें कि आप ऑब्जेक्ट को किसी मौजूदा अनुक्रम में जोड़ना चाहते हैं, या यदि यह ऑब्जेक्ट का अनुक्रम है, तो उन सभी को जोड़ें
try:
my_sequence.extend(o)
except TypeError:
my_sequence.append(o)
इसके साथ एक ट्रिक यह है कि अगर आप स्ट्रिंग्स और / या स्ट्रिंग्स के दृश्यों के साथ काम कर रहे हैं - तो यह मुश्किल है, क्योंकि एक स्ट्रिंग को अक्सर एकल ऑब्जेक्ट के रूप में सोचा जाता है, लेकिन यह पात्रों का एक क्रम भी है। इससे भी बदतर, क्योंकि यह वास्तव में एकल-लंबाई स्ट्रिंग्स का एक क्रम है।
मैं आमतौर पर अपने एपीआई को डिजाइन करने के लिए चुनता हूं ताकि यह केवल एक मूल्य या एक अनुक्रम को स्वीकार करे - यह चीजों को आसान बनाता है। इसे लगाना मुश्किल नहीं है[ ]
जब आप इसे ज़रूरत में पास करते हैं, तो अपने एकल मूल्य के आसपास है।
(हालांकि यह तार के साथ त्रुटियों का कारण बन सकता है, क्योंकि वे अनुक्रम की तरह दिखते हैं (हैं)।)
प्रकार की जांच करने का एक सरल तरीका यह है कि आप जिस चीज़ को जानते हैं, उससे उसकी तुलना करें।
>>> a = 1
>>> type(a) == type(1)
True
>>> b = 'abc'
>>> type(b) == type('')
True
मुझे लगता है कि सबसे अच्छा तरीका है कि आप अपने चर को अच्छी तरह से टाइप करें। आप "टाइपिंग" लाइब्रेरी का उपयोग करके ऐसा कर सकते हैं।
उदाहरण:
from typing import NewType
UserId = NewType ('UserId', int)
some_id = UserId (524313
) `
आप निम्न पंक्ति के साथ जाँच कर सकते हैं कि दिया गया मान किस प्रकार का है:
def chr_type(chrx):
if chrx.isalpha()==True:
return 'alpha'
elif chrx.isdigit()==True:
return 'numeric'
else:
return 'nothing'
chr_type("12)