2010-02-17 22 views
13

en Python 2.5, tengo el siguiente código en un módulo llamado modtest.py:¿Cómo obtengo el nombre del módulo de la definición de clase de un objeto en lugar del nombre del módulo de la instanciación del objeto?

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

Sin embargo, cuando ejecuto esto, se imprime:

__main__ 

si creo un segundo archivo modtest2.py llamada y ejecutarlo:

import modtest 

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

Esto muestra:

modtest 

¿Cómo puedo cambiar el decorador para que siempre imprima modtest, el nombre del módulo en el que se define la clase?

Respuesta

9

Cuando ejecuta directamente un archivo de origen python, el nombre del módulo de ese archivo es __main__, incluso si se lo conoce con otro nombre cuando ejecuta algún otro archivo e lo importa.

Probablemente desee hacer lo mismo que en modtest2, e importar el módulo que contiene la definición de clase en lugar de ejecutar ese archivo directamente. Sin embargo, puede obtener el nombre del archivo del módulo principal para fines de diagnóstico:

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

Esta es una buena respuesta. ¿Es posible obtener la ruta completa del módulo como la devuelve el propio .__ module__ en lugar de solo el nombre del archivo del módulo? –

+0

No estoy seguro de que pueda hacer eso con precisión con facilidad. Podrías aproximarlo caminando por el árbol del directorio (comenzando con el directorio de '__file__') y buscando archivos llamados' __init __. Py' en cada uno, deteniéndote cuando no encuentras uno, y luego machacando los segmentos del camino junto con puntos. Esperaría que esto difiera de la verdadera ruta completa del módulo en algunos casos. –

+0

Este método podría funcionar, pero para dos módulos python de relación desconocida ¿es posible obtener el directorio del archivo? –

-1

Supongo que puede usar sys._getframe() hackeo para obtener lo que quiere.

+0

Al considerar eso, creo que el problema es que el método aún no ha sido llamado, entonces no estoy seguro si hay alguna información en la pila de marcos que pueda usar. –

+0

Sin embargo, se ha llamado al decorador desde el ámbito de clases, así que supongo que todavía puede hacer algo allí ... – djc

+0

sys._getframe(). F_code.co_filename funciona hasta cierto punto, pero solo tengo el nombre de archivo de el módulo, no la ruta completa. –

Cuestiones relacionadas