2016-12-08 206 views
1

我嘗試從python文件中使用python獲取類的列表。一些搜索後,我得到的,我認爲這是工作如下獲取python文件中類的列表

def get_class_from_file(class_obj, file, path='app', exclude=[]): 
    class_list = [] 
    module = importlib.import_module(path + '.' + file) 
    for x in dir(module) : 
     app_cls = getattr(importlib.import_module(path + '.' + file), x) 
     try : 
      if app_cls and issubclass(app_cls, class_obj) and app_cls != class_obj and app_cls not in exclude: 
       class_list.append((file, x)) 
     except TypeError : 
      pass 
    return class_list 

不過,我發現的代碼沒有得到只有類的列表的代碼,但它仍然保持向我展示了超裏面的文件之類的,我這裏是

file_1.py

class A: 
    pass 

class B(A): 
    pass 

file_2.py

class C(B): 
    pass 

class D: 
    pass 

當我調用函數作爲 class_list = get_class_from_file(A, 'file_2')

我期望的結果將是[C],但它返回[C,B]爲B是超類的Ç

之一

請幫我解決這個問題,我只想在給定文件中的類,而不是它們的任何超類。順便說一下,我首先使用排除來修復它,但它不給我一個長期的解決方案。

+1

在file_2.py中,您可能有'from file_1 import A'。這意味着從那時開始,A在file_2和file_1中。 – RemcoGerlich

+0

@RemcoGerlich答案是正確的,我只想補充說,這個任務並不像你想象的那麼微不足道。如果有'A類:通過'和'B = A'會怎麼樣?這個文件中有兩個類還是一個類?班級名單將包含一個愚蠢的,也許這就是你想要的,也許不是。 –

+0

@ŁukaszRogalski:是的,即使你想做一些事情,比如保存一套已經找到的id(),你也不能控制A或B。但也許他的用例是這樣的,他沒有這些問題。 – RemcoGerlich

回答

2

問題是還發現導入的模塊。您可以檢查課程' __module__屬性以查看它是源自當前模塊還是已導入它。

你也有importlib.import_module(path + '.' + file)兩次,我刪除了其中一個。我將其更名爲xname

def get_class_from_file(class_obj, file, path='app', exclude=[]): 
    class_list = [] 
    module_path = path + '.' + file 
    module = importlib.import_module(module_path) 
    for name in dir(module) : 
     app_cls = getattr(module, name) 
     try: 
      if (issubclass(app_cls, class_obj) and 
       app_cls != class_obj and 
       app_cls not in exclude and 
       app_cls.__module__ == module_path): 
      class_list.append((file, name)) 
     except TypeError: 
      # Not a class 
      pass 
    return class_list 
+0

謝謝,這是工作。 – Chetchaiyan