2017-02-19 19 views
2

我正在寫一個包含幾個嵌套類小Python應用程序,如下面的例子:python - 如何獲得內部類的列表?

class SuperBar(object): 
    pass 

class Foo(object): 
    NAME = 'this is foo' 

    class Bar(SuperBar): 
     MSG = 'this is how Bar handle stuff' 

    class AnotherBar(SuperBar): 
     MSG = 'this is how Another Bar handle stuff' 

我使用嵌套類來創建某種層次結構,並提供一個乾淨的方式來實現的功能爲解析器。

在某些時候,我想創建一個內部類的列表。我想有以下輸出:

[<class '__main__.Bar'>, <class '__main__.AnotherBar'>] 

的問題是:什麼是推薦的方法,以獲取在Python的方式內部類的列表?

+0

1.你爲什麼要嵌套班,你能給出更多的背景嗎? 2.你不是隻想要'SuperBar'的所有子類(在這種情況下請參閱http://stackoverflow.com/q/3862310/3001761)? – jonrsharpe

+0

這還不夠。在實際的應用程序中,我有更多的根類,比如'Foo',有更多的內部類來完成解析樹。我還需要強制執行一個給定的令牌(比如'Bar')來到根令牌'Foo'的上下文中。爲了捕獲這種層次結構,我使用這些內部類。 - 謝謝 –

+0

然後[編輯]給更多的上下文。你可能試圖完全解決錯誤的問題。 – jonrsharpe

回答

1

我設法得到內部類對象的列表下面的方法:

import inspect 

def inner_classes_list(cls): 
    return [cls_attribute for cls_attribute in cls.__dict__.values() 
      if inspect.isclass(cls_attribute) 
      and issubclass(cls_attribute, SuperBar)] 

它的工作原理,但我不知道,如果使用__dict__是直接做一件好事。我正在使用它,因爲它包含我需要的實際的class實例,似乎可以跨Python 2和3移植。

+0

是的 - 你可以使用__dict__ - 它是更加普遍的地方和有用的thna使用嵌套類。 - 但是通過查看'__dict__',你看不到任何超類的屬性。檢查我的答案。 – jsbueno

1

第一:我看不出嵌套類如何適合您。一旦你有一個fFoo實例,你是否意識到f.Barf.AnotherBar將是所有實例的相同對象?即 - 您無法在f.Bar上記錄f的任何屬性,如f.Bar.speed - 或者它將與來自另一個實例g.Bar.speed的屬性發生衝突。

爲了克服這個問題,實際上唯一有意義的東西,您需要將實例BarAnotherBar附加到實例f。這些實例通常不能在類體上聲明 - 你必須在Foo的__init__方法中創建它們。

Bar和AntherBar可以做的唯一事情是:(1)有很多類和靜態方法,然後它們只作爲名稱空間工作。

或者,如果SuperBar元類或本身實現描述協議 - https://docs.python.org/3/reference/datamodel.html#implementing-descriptors - 但他們,你會好得多,如果superbar本身將實現描述prootocol(由具有或者__get____set__方法),並連接到Foo的身體,你會有這些類的實例,而不是類本身。

也就是說,您使用__dict__獲得內部類的解決方案:如果Foo本身繼承自其他也具有嵌套類的類,則該方法無效。 Foo的超類永遠不會被搜索。你可以有一個方法,無論是看對Foo的__mro__所有類,或簡單地使用dirissubclass

class Foo: 
    @classmethod 
    def inner_classes_list(cls): 
      results = [] 
      for attrname in dir(cls): 
       obj = getattr(cls, attrname) 
       if isinstance(obj, type) and issubclass(obj, SuperBar): 
        results.append(obj) 
      return results 

(如果你想這個工作對所有類,如美孚,不共用一個基地,如果它不被聲明爲一個類方法,那麼相同的代碼將起作用 - 並且,如果您有多個嵌套類層次結構,則SuperBar可以是此函數的參數。)

現在你有了這個,我們強烈要求你提出其他問題,說明你想要實際做什麼 - 並閱讀關於「描述符」 - 甚至是「屬性」。真的:人們對嵌套子類的用處很少。

相關問題