यदि एक वर्ग दूसरे का उपवर्ग है तो मैं कैसे (रनटाइम पर) जांच करूं?


196

मान लीजिए कि मेरे पास एक सूट है और सूट के चार उपवर्ग हैं: हार्ट, स्पेड, डायमंड, क्लब।

class Suit:
   ...
class Heart(Suit):
   ...
class Spade(Suit):
   ...
class Diamond(Suit):
   ...
class Club(Suit):
   ...

मेरे पास एक विधि है जो एक पैरामीटर के रूप में एक सूट प्राप्त करती है, जो कि एक क्लास ऑब्जेक्ट है, उदाहरण के लिए नहीं। अधिक सटीक रूप से, यह चार मूल्यों में से केवल एक को प्राप्त कर सकता है: हार्ट, स्पेड, डायमंड, क्लब। मैं ऐसी बात कैसे सुनिश्चित कर सकता हूं? कुछ इस तरह:

def my_method(suit):
   assert(suit subclass of Suit)
   ...

मैं पायथन 3 का उपयोग कर रहा हूं।


1
@ तेंदुआ: क्या यह वास्तव में स्पष्ट नहीं है? मैंने वास्तव में कहा है कि संभावित चार मान क्या हैं जो my_methodपैरामीटर के रूप में प्राप्त कर सकते हैं: "यह चार मूल्यों में से केवल एक को प्राप्त कर सकता है: हार्ट, स्पेड, डायमंड, क्लब"। वे मूल्य वर्ग वस्तुएं हैं, वर्ग उदाहरण नहीं। यह मुझे बहुत स्पष्ट लगता है, हालांकि मुझे लगता है कि आप अस्पष्टता के बारे में सही हैं क्योंकि उत्तर दोनों संभावनाओं को कवर करते हैं। यदि आपके पास इसके लिए एक स्पष्ट शब्द है, तो प्रश्न को संपादित करने के लिए आपका स्वागत है। टिप्पणी के लिए धन्यवाद।
सायंकाल

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

1
@snakile कि, और यह बात कि यह एक नामकरण सम्मेलन का उपयोग करने के लिए उचित हो सकता है जो इस तरह के पैरामीटर नामों के साथ प्रत्यय लगाता है, जैसे _classबनाना suit_class। मैंने एक प्रासंगिक प्रश्न में इस तरह के नामकरण सम्मेलन का प्रस्ताव रखा
n611x007

उदाहरण कोड चार लाइनों को जोड़ने का सुझाव दें my_method(Heart) my_method(Spade)...
बॉब स्टेन

ऐसे मामलों के लिए जहां परीक्षण किए जा रहे चर को एक वर्ग होने की गारंटी नहीं है, आप पायथन 3 में एक शर्त जोड़ सकते हैं inspect.isclassया बस उपयोग कर सकते हैं isinstance(myvar, type), क्योंकि issubclassयह एक गैर-वर्ग पास होने पर एक त्रुटि उत्पन्न करेगा। इस जवाब को देखें । मैंने नीचे दिए गए उत्तर पर टिप्पणी की होगी, लेकिन यह कभी भी दिन की रोशनी को नहीं देखा होगा।
कुल

जवाबों:


224

आप issubclass()इस तरह का उपयोग कर सकते हैं assert issubclass(suit, Suit)


55
"लेकिन आप ऐसा काम क्यों करना चाहेंगे?" - क्योंकि आपके पास एक कंटेनर वर्ग है जिसे आपको सुनिश्चित करने की आवश्यकता है कि सजातीय है, और ऐसा करने का एकमात्र तरीका डालने पर प्रकार की जांच करना है?
एडम पार्किन

140
यदि स्टैक ओवरफ्लो पर एक चीज है जो स्थिर है, तो यह है कि उत्तर के साथ कोई भी प्रश्न जिसका अर्थ है आइंस्टीनेंस या आइसक्यूक्लास भी बतख टाइपिंग के बारे में व्याख्यान के साथ होगा!
बेन रॉबर्ट्स

26
मैं इस सवाल के बारे में जानने की कोशिश कर रहा था कि कैसे पता लगाया जाए कि मेरा सुन्न dtype एक फ्लोट है या एक इमेज प्रोसेसिंग एप्लिकेशन के लिए एक इंट। यदि यह एक फ्लोट है, तो कन्वेंशन 0.0 और 1.0 के बीच सामान्य करना है, यदि यह int है तो कन्वेंशन 0 से 255 है। मैं इमेज को क्वैक करने के लिए सभी प्रकार के कंट्रोवर्सीज से गुजर सकता हूं, लेकिन इमेज को आगे बढ़ाने के लिए यह बहुत ही सीधा है। बस पूछें "क्या आप एक बतख हैं" और तदनुसार मेरे संचालन को मापें।
ओमेगमैन

28
उपवर्ग परीक्षण कई चीजों की इकाई परीक्षण करता है, विशेष रूप से Django के मॉडल, बहुत आसान है। "पायथन जावा नहीं है।" अजगर के प्रोग्रामर के कंधे पर ऐसे चिप्स क्यों होने चाहिए?
माइकल बेकन

20
अपवित्र नहीं, अंत में अकल्पनीय और बल्कि अभिमानी टिप्पणी के कारण। इस बारे में एक स्पष्टीकरण कि किसी को ऐसा करने की आवश्यकता क्यों नहीं हो सकती, यह मित्रवत और अधिक सहायक होगा।
माइकल स्काइपर


26

isinstanceयदि आपके पास कोई उदाहरण है, या issubclassयदि आपके पास एक वर्ग है , तो आप इसका उपयोग कर सकते हैं । सामान्य रूप से इसका बुरा विचार है। आम तौर पर पायथन में आप काम करते हैं यदि कोई वस्तु उस चीज को करने का प्रयास करके किसी चीज के लिए सक्षम है।


क्या होगा अगर आपको पता चले कि आप इसके साथ उस चीज़ को नहीं कर सकते हैं? क्या आप एक अपवाद को पकड़ते हैं और कुछ और कोशिश करते हैं?
गलत काम

2
@wrongusername: यह 'पायथोनिक' तरीका है, हाँ। मुझे लगता है कि इस रिवाज में योग्यता है, इसलिए मैं इसका पालन करता हूं जब तक कि यह मेरे कोड को स्पष्ट रखता है। इसके बारे में यहाँ एक अच्छी चर्चा है: stackoverflow.com/questions/7604636/…
माइकल शेफ़र

8
@ मिचेल शेपर: मुझे कहना होगा, अगर वह पाइथोनिक तरीका है, तो मुझे पाइथोनिक तरीके से नफरत है। नियंत्रण प्रवाह के लिए IMO, अपवादों का उपयोग नहीं किया जाना चाहिए। अगर आपको लगता है कि कोई त्रुटि हो सकती है, तो उसके खिलाफ सुरक्षा करें ... इसे गोटो की तरह न समझें। दिलचस्प लिंक जो आपने पोस्ट किया, हालांकि
लेविथानबर्गर

@ उपर्युक्त: लगता है कि जिस तरह के मामलों में आप उल्लंघन कर रहे हैं, 'जब तक यह मेरा कोड स्पष्ट है'। मैं सभी पाइथोनिक रीति-रिवाजों का प्रशंसक नहीं हूं, हालांकि, बहुत से लोग ईएएफपी सिद्धांत का दुरुपयोग करते हैं और मुश्किल से ढूंढने वाले कीड़े पैदा करते हैं।
माइकल शेपर 19

अनुबंधों को परिभाषित करते समय यह जांच काम आती है। उदाहरण के लिए, एक कंस्ट्रक्टर जो एक ऑब्जेक्ट प्राप्त करता है: हम यह दावा करना चाहते हैं कि प्राप्त ऑब्जेक्ट एक दिए गए वर्ग का एक उदाहरण है, और ऐसा करके हम कोड रीडर को सूचित करते हैं कि कंस्ट्रक्टर को क्या उम्मीद है।
मस्टरोपी


2

issubclass न्यूनतम चल उदाहरण

यहाँ कुछ कथनों के साथ एक और पूर्ण उदाहरण दिया गया है:

#!/usr/bin/env python3

class Base:
    pass

class Derived(Base):
    pass

base = Base()
derived = Derived()

# Basic usage.
assert issubclass(Derived, Base)
assert not issubclass(Base, Derived)

# True for same object.
assert issubclass(Base, Base)

# Cannot use object of class.
try:
    issubclass(derived, Base)
except TypeError:
    pass
else:
    assert False

# Do this instead.
assert isinstance(derived, Base)

गिटहब ऊपर

पायथन 3.5.2 में परीक्षण किया गया।


1

आप बिलिन आइसबक्लास का उपयोग कर सकते हैं। लेकिन प्रकार की जाँच को आमतौर पर अस्वाभाविक के रूप में देखा जाता है क्योंकि आप डक-टाइपिंग का उपयोग कर सकते हैं।


1

Issubclass का उपयोग करना एक साफ तरीके की तरह लग रहा था कि loglevels लिखना है। यह थोड़े इसे उपयोग करने में अजीब लगता है ... लेकिन यह अन्य विकल्पों की तुलना में क्लीनर लगता है।

class Error(object): pass
class Warn(Error): pass
class Info(Warn): pass
class Debug(Info): pass

class Logger():
    LEVEL = Info

    @staticmethod
    def log(text,level):
        if issubclass(Logger.LEVEL,level):
            print(text)
    @staticmethod
    def debug(text):
        Logger.log(text,Debug)   
    @staticmethod
    def info(text):
        Logger.log(text,Info)
    @staticmethod
    def warn(text):
        Logger.log(text,Warn)
    @staticmethod
    def error(text):
        Logger.log(text,Error)

0

पायथन डॉक के अनुसार , हम class.__mro__विशेषता या class.mro()विधि का भी उपयोग कर सकते हैं :

class Suit:
    pass
class Heart(Suit):
    pass
class Spade(Suit):
    pass
class Diamond(Suit):
    pass
class Club(Suit):
    pass

>>> Heart.mro()
[<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>]
>>> Heart.__mro__
(<class '__main__.Heart'>, <class '__main__.Suit'>, <class 'object'>)

Suit in Heart.mro()  # True
object in Heart.__mro__  # True
Spade in Heart.mro()  # False

-5
#issubclass(child,parent)

class a:
    pass
class b(a):
    pass
class c(b):
    pass

print(issubclass(c,b))#it returns true

1
एसओ पर कोड-केवल उत्तर की सराहना नहीं की जाती है, आपको हमेशा कोड में कुछ व्याख्यात्मक पाठ जोड़ना चाहिए। हालाँकि, यह उत्तर अतिश्योक्तिपूर्ण है: इसमें ऐसी कोई जानकारी नहीं है जो पिछले उत्तर में पहले से उल्लेखित नहीं है।
PM 2Ring
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.