2010-11-04 8 views
5

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

def bases(cls): 
    yield cls 
    for direct_base in cls.__bases__: 
     for base in bases(direct_base): 
      yield base 

मेरे लिए यह करने के लिए एक मानक समारोह है:

ऐसा करने के लिए, मैं निम्नलिखित लिखा?

उत्तर

12

एक विधि है जो विधि समाधान आदेश (एमआरओ): inspect.getmro में उन सभी को वापस कर सकती है। यहाँ देखें:

http://docs.python.org/library/inspect.html#inspect.getmro

यह उन्हें एक टपल, जिसे फिर आप अपने आप को एक एकल पाश में अधिक पुनरावृति कर सकते हैं के रूप में प्रस्तुत करती है:

import inspect 
for base_class in inspect.getmro(foo): 
    # do something 

यह केवल प्रत्येक आधार वर्ग एक बार उपज के पक्ष लाभ है , भले ही आपके पास हीरा-पैटर्न वाली विरासत हो।

0

मैं बिल्कुल पता नहीं है अगर यह होता है कि आप क्या ढूंढ रहे हैं, लेकिन someclass.__mro__ पर एक नजर है, एमआरओ जा रहा है विधि संकल्प आदेश

http://docs.python.org/library/stdtypes.html?highlight=mro#class.__mro__

+1

इसमें पुरानी शैली के वर्गों के साथ काम नहीं करने का तर्क (तर्कसंगत) नुकसान है। 'inspect.getmro' रिटर्न' cls .__ mro__' अगर यह मौजूद है (जो यह नई शैली कक्षाओं पर है) और यदि यह नहीं है तो कस्टम खोज करता है। (मजेदार तथ्य: आप अधिकतम रिकर्सन गहराई की तुलना में अधिक कक्षाओं के साथ पुरानी स्टाइल क्लास पदानुक्रम बनाकर और 'गेट्रो' को कॉल करके एक रिकर्सन त्रुटि उत्पन्न कर सकते हैं) – aaronasterling

1

एम्बर के लिए सही जवाब है वास्तविक दुनिया, लेकिन मैं ऐसा करने के लिए एक सही तरीका दिखाऊंगा। यदि आपके दो आधार वर्ग स्वयं एक ही बेस क्लास से प्राप्त होते हैं तो आपके समाधान में दो कक्षाएं शामिल होंगी।

def bases(cls): 
    classes = [cls] 
    i = 0 
    while 1: 
     try: 
      cls = classes[i] 
     except IndexError: 
      return classes 
     i += 1 
     classes[i:i] = [base for base in cls.__bases__ if base not in classes] 

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

+0

धन्यवाद। मुझे एहसास हुआ कि मैंने पोस्ट किया है कि मेरा दो बार एक ही कक्षा में हिट हो सकता है लेकिन मेरे मामले में इससे कोई फर्क नहीं पड़ता। –

संबंधित मुद्दे