2010-02-17 146 views
13

在Python 2.5中,我有一個模塊在下面的代碼名爲modtest.py:如何獲取對象類定義的模塊名稱而不是對象實例化的模塊名稱?

def print_method_module(method): 
    def printer(self): 
     print self.__module__ 
     return method(self) 
    return printer 

class ModTest(): 

    @print_method_module 
    def testmethod(self): 
     pass 

if __name__ == "__main__": 
    ModTest().testmethod() 

然而,當我運行它,它打印出:

__main__ 

如果我創建第二個文件所謂modtest2.py並運行它:

import modtest 

if __name__ == "__main__": 
    modtest.ModTest().testmethod() 

此打印出:

modtest 

如何更改裝飾器,始終打印出modtest,該類定義的模塊的名稱?

回答

9

當您直接執行python源文件時,該文件的模塊名稱爲__main__,即使您在執行某個其他文件並將其導入時被另一個名稱所知。

您可能想要像在modtest2中那樣做,然後導入包含類定義的模塊,而不是直接執行該文件。但是,爲了您的診斷目的,您可以獲取主模塊的文件名,如下所示:

def print_method_module(method): 
    def printer(self): 
     name = self.__module__ 
     if name == '__main__': 
      filename = sys.modules[self.__module__].__file__ 
      name = os.path.splitext(os.path.basename(filename))[0] 
     print name 
     return method(self) 
    return printer 
+0

這是一個很好的答案。是否有可能得到完整的模塊路徑,就像self.__ module__返回的那樣,而不僅僅是模塊文件名? –

+0

我不確定您是否可以輕鬆地做到這一點。你可以通過在目錄樹上行走(從'__file__'開始)並尋找名爲'__init __。py'的文件,當你沒有找到文件時停下來,然後將路徑段與點。我希望這在某些情況下會與真正的完整模塊路徑不同。 –

+0

這種方法可以工作,但對於未知關係的兩個python模塊是否可以獲取文件的目錄? –

-1

我猜你可以使用sys._getframe()hackery來得到你想要的。

+0

調查一下,我認爲問題在於該方法尚未實際調用,所以我沒有確定是否有任何可以使用的幀堆棧中的信息。 –

+0

儘管從類範圍調用了裝飾器,所以我想你仍然可以在那裏做些什麼...... – djc

+0

sys._getframe()。f_code.co_filename工作到一個點,但我仍然只有文件名該模塊,而不是完整的路徑。 –