2016-12-08 6 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 
例です

Iは class_list = get_class_from_file(A、 'file_2')としての機能を呼び出す

私は結果は[C]であろう期待するが、BはC

のスーパークラスの一つであるとして、それは[C、B]を返します

私はこれを修正するのを手伝ってください、私はちょうど与えられたファイルの中にクラスを入れたい、彼らのスーパークラスではありません。ちなみに、私は最初にそれを修正するために除外を使用しますが、それは私に長期的な解決策を与えていません。

+1

file_2.pyには、おそらく 'from file_1 import A 'があります。つまり、それ以降、Aはfile_1と同様にfile_2にあります。 – RemcoGerlich

+0

@RemcoGerlichの答えは正しいです、私はちょうどあなたが思うほど些細なことではないということを付け加えたいと思います。 'class A:pass'と' B = A'があればどうなりますか?このファイルには2つのクラスまたは1つのクラスがありますか?クラスリストには二重引用符が含まれていますが、多分それはあなたが望むものかもしれません。 –

+0

@ŁukaszRogalski:はい、すでに見つかったid()のセットを保持するようなことをしても、最初にAまたはBが見つかるのをコントロールできません。しかし、彼のユースケースは、彼がそのような問題を抱えていないようなものかもしれない。 – RemcoGerlich

答えて

2

問題は、インポートされたモジュールも見つかりました。クラスの ' __module__'属性をチェックして、現在のモジュールからのものか、またはそのモジュールにインポートされたものかを確認できます。

あなたはまたimportlib.import_module(path + '.' + file)を2度持っていますが、そのうちの1つを削除しました。私は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

関連する問題