2010-02-17 17 views
13

W Pythonie 2.5, mam następujący kod w module o nazwie modtest.py:W jaki sposób uzyskać nazwę modułu definicji klasy obiektu zamiast nazwy modułu procesu tworzenia obiektu?

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() 

Jednak gdy uruchamiam to, że wypisuje:

__main__ 

Jeśli utworzyć drugi plik nazywa modtest2.py i uruchom go:

import modtest 

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

ten wypisuje:

modtest 

Jak zmienić dekorator, aby zawsze drukować modtest, nazwę modułu, w którym zdefiniowano klasę?

Odpowiedz

9

Po bezpośrednim uruchomieniu pliku źródłowego Pythona, nazwa modułu tego pliku to __main__, nawet jeśli jest znana innej nazwie po wykonaniu innego pliku i zaimportowaniu go.

Prawdopodobnie chcesz zrobić to, co zrobiłeś w modtest2, i zaimportować moduł zawierający definicję klasy, zamiast bezpośrednio wykonywać ten plik. Można jednak uzyskać nazwę pliku głównego modułu, jak na przykład dla celów diagnostycznych:

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

To jest dobra odpowiedź. Czy jest możliwe, aby uzyskać pełną ścieżkę modułu zwróconą przez self .__ moduł__ zamiast tylko nazwę pliku modułu? –

+0

Nie jestem pewien, czy możesz to zrobić dokładnie z łatwością. Możesz to przybliżyć, podchodząc do drzewa katalogów (zaczynając od katalogu '__file__') i szukając w każdym z nich plików o nazwie' __init __. Py', zatrzymując się, gdy go nie znajdziesz, a następnie łącząc segmenty ścieżek z kropki. Spodziewałbym się, że w niektórych przypadkach różni się to od prawdziwej ścieżki pełnego modułu. –

+0

Ta metoda może działać, ale w przypadku dwóch modułów python o nieznanej relacji możliwe jest uzyskanie katalogu pliku? –

-1

Zgaduję, że można użyć hackery sys._getframe(), aby uzyskać to, co chcesz.

+0

Patrząc na to, myślę, że problem polega na tym, że metoda nie została jeszcze wywołana, więc nie jestem pewnie, jeśli w stosie klatek są jakieś informacje, których mogę użyć. –

+0

Dekorator został wywołany z klasy, chociaż, tak myślę, że nadal możesz coś tam zrobić ... – djc

+0

sys._getframe(). F_code.co_filename działa do punktu, ale wciąż mam tylko nazwę pliku moduł, a nie pełna ścieżka. –

Powiązane problemy