दिलचस्प पोस्ट
तार बनाने के लिए सी मैक्रोज़ स्विफ्ट में निब से कस्टम UITableViewCell Google Analytics API v3 के साथ OAuth 2.0 लगातार डेटा संग्रहण के लिए SQLite या साझा किए गए संदर्भ? सी में एंट / यूआईटी में कनवर्ट बाइट्स मैं लिनक्स (एएलएफ) बाइनरी के सीधा साझा ऑब्जेक्ट निर्भरता कैसे प्राप्त करूं? एक दृश्य को केवल तभी निकालना जब कीबोर्ड इनपुट फ़ील्ड को कवर करता है एंड्रॉइड में एक्सेस संसाधन फाइलें आप एक बीटा परीक्षण कैसे कर सकते हैं एक iphone app? मैं TabControl के अंदर एक टैब कैसे अक्षम कर सकता हूं? एंड्रॉइड में देरी कैसे तय करें? रूबी में "नक्शा" विधि क्या करती है? Async WebApi थ्रेड। वर्तमान कृषि CSS के साथ स्वरूपण संख्या (दशमलव स्थान, हजारों विभाजक, आदि) सी ++ में आप किस प्रकार की एन्यूम का उपयोग कर रहे हैं?

मैं अपने वर्ग के सभी उपवर्गों को कैसे अपनाया?

मुझे सभी कक्षाएं प्राप्त करने का एक कार्यशील दृष्टिकोण चाहिए जो कि पायथन में बेस क्लास से विरासत में मिलते हैं।

Solutions Collecting From Web of "मैं अपने वर्ग के सभी उपवर्गों को कैसे अपनाया?"

न्यू-स्टाइल कक्षाएं (अर्थात object से उपवर्ग, जो कि पायथन 3 में डिफ़ॉल्ट है) में एक __subclasses__ विधि है जो उप- __subclasses__ देता है:

 class Foo(object): pass class Bar(Foo): pass class Baz(Foo): pass class Bing(Bar): pass 

उपवर्गों के नाम यहां दिए गए हैं:

 print([cls.__name__ for cls in vars()['Foo'].__subclasses__()]) # ['Bar', 'Baz'] 

यहां स्वयं उपवर्ग हैं:

 print(vars()['Foo'].__subclasses__()) # [<class '__main__.Bar'>, <class '__main__.Baz'>] 

पुष्टिकरण कि उपवर्ग वास्तव में Foo को उनके आधार के रूप में सूचीबद्ध करते हैं:

 for cls in vars()['Foo'].__subclasses__(): print(cls.__base__) # <class '__main__.Foo'> # <class '__main__.Foo'> 

नोट करें कि आप subsubclasses चाहते हैं, आपको recurse करना होगा:

 def all_subclasses(cls): return cls.__subclasses__() + [g for s in cls.__subclasses__() for g in all_subclasses(s)] print(all_subclasses(vars()['Foo'])) # [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] 

अगर आप सीधे subclasses चाहते हैं तो .__subclasses__() ठीक काम करता है यदि आप सभी उपवर्ग, उप-वर्गों के उप-वर्ग और अन्य सभी करना चाहते हैं, तो आपके लिए ऐसा करने के लिए आपको फ़ंक्शन की आवश्यकता होगी।

यहां एक सरल, पठनीय कार्य है जो कि किसी दिए गए वर्ग के सभी उपवर्गों को बार-बार पाता है:

 def get_all_subclasses(cls): all_subclasses = [] for subclass in cls.__subclasses__(): all_subclasses.append(subclass) all_subclasses.extend(get_all_subclasses(subclass)) return all_subclasses 

सामान्य रूप में सरल उपाय:

 def get_subclasses(cls): for subclass in cls.__subclasses__(): yield from get_subclasses(subclass) yield subclass 

और एक क्लासपैथि के मामले में आपके पास एक ही क्लास होता है जहां से आप इनसे प्राप्त करते हैं:

 @classmethod def get_subclasses(cls): for subclass in cls.__subclasses__(): yield from subclass.get_subclasses() yield subclass 

पायथन 3.6__init_subclass__

जैसा कि अन्य उत्तर में आप उप-वर्गों की सूची प्राप्त करने के लिए __subclasses__ विशेषता की जांच कर सकते हैं, क्योंकि अजगर 3.6 आप __init_subclass__ विधि को ओवरराइड करके इस विशेषता निर्माण को संशोधित कर सकते हैं।

 class PluginBase: subclasses = [] def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls.subclasses.append(cls) class Plugin1(PluginBase): pass class Plugin2(PluginBase): pass 

इस तरह, यदि आप जानते हैं कि आप क्या कर रहे हैं, तो आप __subclasses__ subclasses__ के व्यवहार को ओवरराइड कर सकते हैं और इस सूची से उप- __subclasses__ जोड़ सकते हैं।

एफडब्ल्यूआईडब्ल्यू , यहां जो कि मेरा मतलब है @ यूनटबू का जवाब केवल स्थानीय रूप से परिभाषित वर्गों के साथ काम करना है – और यह कि वाल eval() बजाय vars() करना किसी भी सुलभ वर्ग के साथ काम करता है, न कि केवल मौजूदा क्षेत्र में परिभाषित किया गया है

उन लोगों के लिए जो eval() का उपयोग नापसंद करते हैं, एक तरह से इसे से बचने के लिए भी दिखाया गया है

सबसे पहले यहां एक ठोस उदाहरण है जिसमें vars() का उपयोग करने के साथ संभावित समस्या का प्रदर्शन किया गया है:

 class Foo(object): pass class Bar(Foo): pass class Baz(Foo): pass class Bing(Bar): pass # unutbu's approach def all_subclasses(cls): return cls.__subclasses__() + [g for s in cls.__subclasses__() for g in all_subclasses(s)] print(all_subclasses(vars()['Foo'])) # Fine because Foo is in scope # -> [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] def func(): # won't work because Foo class is not locally defined print(all_subclasses(vars()['Foo'])) try: func() # not OK because Foo is not local to func() except Exception as e: print('calling func() raised exception: {!r}'.format(e)) # -> calling func() raised exception: KeyError('Foo',) print(all_subclasses(eval('Foo'))) # OK # -> [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] # using eval('xxx') instead of vars()['xxx'] def func2(): print(all_subclasses(eval('Foo'))) func2() # Works # -> [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] 

यह eval('ClassName') को परिभाषित समारोह में नीचे ले जाकर सुधार किया जा सकता है, जो इसे eval() का उपयोग करके प्राप्त अतिरिक्त सामान्यता की हानि के बिना इसे आसान बना देता है जो vars() विपरीत संदर्भ-संवेदनशील नहीं है:

 # easier to use version def all_subclasses2(classname): direct_subclasses = eval(classname).__subclasses__() return direct_subclasses + [g for s in direct_subclasses for g in all_subclasses2(s.__name__)] # pass 'xxx' instead of eval('xxx') def func_ez(): print(all_subclasses2('Foo')) # simpler func_ez() # -> [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] 

अंत में, यह संभव है, और संभवतः कुछ मामलों में भी महत्वपूर्ण है, सुरक्षा कारणों से eval() का उपयोग करने से बचने के लिए, इसलिए यहां इसके बिना एक संस्करण है:

 def get_all_subclasses(cls): """ Generator of all a class's subclasses. """ try: for subclass in cls.__subclasses__(): yield subclass for subclass in get_all_subclasses(subclass): yield subclass except TypeError: return def all_subclasses3(classname): for cls in get_all_subclasses(object): if cls.__name__.split('.')[-1] == classname: break else: raise ValueError('class %s not found' % classname) direct_subclasses = cls.__subclasses__() return direct_subclasses + [g for s in direct_subclasses for g in all_subclasses3(s.__name__)] # no eval('xxx') def func3(): print(all_subclasses3('Foo')) func3() # Also works # -> [<class '__main__.Bar'>, <class '__main__.Baz'>, <class '__main__.Bing'>] 

सभी उपवर्गों की सूची प्राप्त करने के लिए एक बहुत छोटा संस्करण:

 from itertools import chain def subclasses(cls): return list( chain.from_iterable( [list(chain.from_iterable([[x], subclasses(x)])) for x in cls.__subclasses__()] ) ) 

यह विशेष रूप से निर्मित __subclasses__() वर्ग पद्धति का उपयोग करने के रूप में उतना अच्छा नहीं है, जो कि @unutbu उल्लेख करते हैं, इसलिए मैं इसे केवल एक अभ्यास के रूप में पेश करता हूं। subclasses() फ़ंक्शन परिभाषित करता है एक शब्दकोश देता है जो सभी उपवर्ग नामों को उप-वर्गों में स्वयं को दर्शाता है

 def traced_subclass(baseclass): class _SubclassTracer(type): def __new__(cls, classname, bases, classdict): obj = type(classname, bases, classdict) if baseclass in bases: # sanity check attrname = '_%s__derived' % baseclass.__name__ derived = getattr(baseclass, attrname, {}) derived.update( {classname:obj} ) setattr(baseclass, attrname, derived) return obj return _SubclassTracer def subclasses(baseclass): attrname = '_%s__derived' % baseclass.__name__ return getattr(baseclass, attrname, None) class BaseClass(object): pass class SubclassA(BaseClass): __metaclass__ = traced_subclass(BaseClass) class SubclassB(BaseClass): __metaclass__ = traced_subclass(BaseClass) print subclasses(BaseClass) 

आउटपुट:

 {'SubclassB': <class '__main__.SubclassB'>, 'SubclassA': <class '__main__.SubclassA'>} 

यहां एक पुनरावर्ती संस्करण नहीं है:

 def get_subclasses_gen(cls): def _subclasses(classes, seen): while True: subclasses = sum((x.__subclasses__() for x in classes), []) yield from classes yield from seen found = [] if not subclasses: return classes = subclasses seen = found return _subclasses([cls], []) 

यह अन्य कार्यान्वयनों से अलग है क्योंकि इसमें मूल वर्ग वापस आ जाता है। इसका कारण यह कोड सरल बनाता है और:

 class Ham(object): pass assert(issubclass(Ham, Ham)) # True 

अगर get_subclasses_gen थोड़ी अजीब दिखता है, क्योंकि यह पूंछ-पुनरावर्ती क्रियान्वयन को एक पाशन-जनरेटर में परिवर्तित करके बनाया गया था:

 def get_subclasses(cls): def _subclasses(classes, seen): subclasses = sum(*(frozenset(x.__subclasses__()) for x in classes)) found = classes + seen if not subclasses: return found return _subclasses(subclasses, found) return _subclasses([cls], []) 

मैं इसके लिए वास्तविक दुनिया उपयोग के मामले की कल्पना नहीं कर सकता, लेकिन एक मजबूत तरीका (पायथन 2 पुरानी शैली वर्गों पर भी) वैश्विक नामों को स्कैन करना होगा:

 def has_children(cls): g = globals().copy() # use a copy to make sure it will not change during iteration g.update(locals()) # add local symbols for k, v in g.items(): # iterate over all globals object try: if (v is not cls) and issubclass(v, cls): # found a strict sub class? return True except TypeError: # issubclass raises a TypeError if arg is not a class... pass return False 

यह पायथन 2 नई शैली वर्गों और पायथन 3 वर्गों के साथ-साथ पायथन 2 क्लासिक क्लासेस पर काम करता है

मैं अपने वर्ग के सभी उपवर्गों को कैसे अपनाया?

हम निश्चित रूप से आसानी से ऑब्जेक्ट के लिए यह दी गई एक्सेस कर सकते हैं, हाँ।

बस अपना नाम दिया गया है, यह एक ख़राब विचार है, क्योंकि एक ही नाम के कई वर्ग हो सकते हैं, यहां तक ​​कि एक ही मॉड्यूल में परिभाषित किया गया है।

मैंने एक और जवाब के लिए एक कार्यान्वयन बनाया, और जब से यह प्रश्न का उत्तर देता है और यहाँ अन्य समाधानों की तुलना में यह थोड़ा और अधिक सुरुचिपूर्ण है, यहां यह है:

 def get_subclasses(cls): """returns all subclasses of argument, cls""" if issubclass(cls, type): subclasses = cls.__subclasses__(cls) else: subclasses = cls.__subclasses__() for subclass in subclasses: subclasses.extend(get_subclasses(subclass)) return subclasses 

उपयोग:

 >>> import pprint >>> list_of_classes = get_subclasses(int) >>> pprint.pprint(list_of_classes) [<class 'bool'>, <enum 'IntEnum'>, <enum 'IntFlag'>, <class 'sre_constants._NamedIntConstant'>, <class 'subprocess.Handle'>, <enum '_ParameterKind'>, <enum 'Signals'>, <enum 'Handlers'>, <enum 'RegexFlag'>]