2017-07-31 25 views
1

我想基於在另一個類的方法內部使用的類來構建依賴關係樹。所以不是父類。爲此,我想檢查一個方法是否使用從名爲Table的特殊類繼承的任何類。獲取方法/函數中使用的類的列表

實施例:

class TestTableOne(Table): 
    """Class for testing table loader""" 
    def source(self): 
     source_file = os.path.join('data', 
            'test_table_one.csv') 
     return pd.read_csv(source_file, dtype=dtype, converters=converters) 

    def output(self): 
     output_path = 'out/path' 
     return output_path 

    def post_processors(self): 
     return [ 
      drop_age_column, 
      calculate_new_age 
     ] 

class TestTableTwo(Table): 
    """Class for testing tables loader""" 
    def source(self): 
     return TestTableOne.fetch() 

    def output(self): 
     output_path = os.path.join(tempfile.mkdtemp(), 
            'output', 
            self.get_cached_filename('test_table_one', 'pkl') 
           ) 
     return output_path 

    def something_does_nothing(self, table): 
     result = TestTableOne.get() 
     return result 

    def post_processors(self): 
     return [ 
      self.something_does_nothing 
     ] 

在這裏,我希望能夠以檢查是否TestTableTwo.source是依賴於從Table繼承,在這種情況下TestTableOne任何其他類。

所以我婉問類似inspect.classes_that_appears_in(TestTableTwo.source)的東西,並得到[TestTableOne]

這是可能在Python?即時通訊使用python 3 btw。

+0

沒有你檢查['__mro__'](https://stackoverflow.com/questions/2010692/what -does-mro-do)魔法? –

+0

如果您使用ast.parse來源,然後使用AST來收集信息,那麼這是可能的。沒有什麼可以做的。如果你幸運的話,可能會有第三方圖書館...... –

+0

@ChihebNexus我認爲這種情況並不合理。 'TestTableTwo.source .__ mro__'不存在我相信,因爲那只是檢查類繼承權的方法解析順序嗎?在這裏,我試圖看到一個類是beeing內部使用的方法。 –

回答

2

那麼這是一個討厭的建議,但你可以試一試:

隨着inspect.getsource你可以得到一個給定對象的源代碼,你可以 對解析您需要的原始文本。

import inspect 

class Table(object): 
    pass 

class TestTableOne(Table): 
    """Class for testing table loader""" 
    def source(self): 
     return None 

class TestTableTwo(Table): 
    """Class for testing tables loader""" 
    def source(self): 
     return TestTableOne.source() 

print(inspect.getsource(TestTableTwo.source)) 
print(TestTableOne.__name__ in inspect.getsource(TestTableTwo.source)) 

這將輸出:

def source(self): 
     return TestTableOne.source() 

True 

我注意到,你還需要一些工作來改進這種方法,以滿足您的要求。

+1

嗯,我正在測試相同的模塊,我想我會回答這個問題。如果你無所謂,我也可以分享我的解決方案。 –

+2

@ChihebNexus隨意做! – Szabolcs

+0

@Szabolcs謝謝:)我會測試一下,看看它是否適用於我,但是如果這基本上只是搜索「TestTableOne」或類似的字符串,我能正確理解它嗎? –

1

下面是使用inspect__mro__一個例子:

class Table: 
    var = "hello" 
    def source(self): 
     return self.var 

class A(Table): 
    def source(self): 
     return Table.source() 

class B(A): 
    def source(self): 
     return A.source() 

class C(B): 
    def source(self): 
     return B.source() 

def check(cls): 
    import inspect 
    func_name = inspect.getsourcelines(cls)[0][1].lstrip().strip('\n').split('return')[1].split('.')[0] 
    func_name_inherits = [k.__name__ for k in eval(func_name + '.__mro__')] 
    if 'Table' in func_name_inherits: 
     return True 
    else: 
     return False 

if __name__== '__main__': 
    print('The return of C.source() inherits from Table:', check(C.source)) 
    print('The return of B.source() inherits from Table:', check(B.source)) 
    print('The return of A.source() inherits from Table:', check(A.source)) 

輸出:

The return of C.source() inherits from Table: True 
The return of B.source() inherits from Table: True 
The return of A.source() inherits from Table: True 
+1

謝謝。我會檢查一下並測試一些東西,然後回來,當我知道我最終做了什麼。 –

+1

@OleHenrikSkogstrøm,基本上你可以使用我們的兩種解決方案,你可以改進他們,直到他們滿足你的需求。 –

相關問題