2010-02-08 13 views
8

Decir que tengo la siguiente clase definida con el método foo:¿Cómo hacer referencia a un nombre de método con un método en Python?

class MyClass: 
    def foo(self): 
     print "My name is %s" % __name__ 

Ahora cuando llamo foo() espero/quieres ver esto imprime

My name is foo 

Sin embargo consigo

My name is __main__ 

Y si tuviera que poner la definición de clase en un módulo llamado FooBar obtendría

My name is FooBar 

Sin embargo, si lo hago

m = MyClass() 
print m.foo.__name__ 

puedo obtener exactamente lo que quiero, que es

My name is foo 

Por favor alguien puede ayudar a explicar por qué __name__ se refiere al módulo y no el nombre del método? ¿Hay alguna manera fácil de obtener el nombre del método?

Muchas gracias

+0

¿por qué necesita para hacer esto? ¿Qué problema estás resolviendo? – SilentGhost

Respuesta

4

nombres se refieren siempre a las variables locales o (si no existe uno), entonces las variables globales. Hay un __name__ global que tiene el nombre del módulo.

class MyClass: 
    def foo(self): 
    print "My name is %s" % MyClass.foo.__name__ 

Por supuesto, eso es redundante y casi completamente inútil. Sólo tienes que escribir el nombre del método:

class MyClass: 
    def foo(self): 
    print "My name is %s" % "foo" 
    print "My name is foo" 
+0

¿Por qué el voto a favor? –

+0

Podría ser un voto negativo competitivo. Me ha pasado esto. – Skurmedel

+1

@Skurmedel: Eso siempre es posible, y les duele más de lo que me afecta (a través de votaciones en respuesta es una ganancia neta para mí, incluso jugable), pero si me he perdido algo, realmente quiero saberlo. –

3

__name__ se refiere al módulo debido that's what it's supposed to do. La única forma de llegar a la función que se está ejecutando actualmente sería introspectivamente la pila.

-1

Esto lo hará:

(. Necesita hacer referencia a self.__class__._name__)

class MyClass: 
    def foo(self): 
     print "My name is %s" % self.__class__.__name__ 
+1

El comportamiento deseado, como se muestra en el ejemplo, está imprimiendo 'foo' (el nombre del método) no 'MyClass'. –

+0

Doh, a la derecha, no leyó la pregunta con cuidado. – 0xfe

11

Esto hace lo que está buscando:


from inspect import currentframe, getframeinfo 

class MyClass: 
    def foo(self): 
     print "My name is %s" % getframeinfo(currentframe())[2] 
+0

Si bien esto es correcto, no hay ninguna razón para preferirlo más que simplemente escribir 'foo' en el cuerpo de la función sin mucha más información del OP. –

+0

Genial, me pregunto si se podría hacer un decorador que haga esto de alguna manera ... Al menos después de que se haya ejecutado el método decorado. Tal vez podrías inspeccionar el método decorado. – Skurmedel

+0

@Skurmedel: 'def with_name (fn): return lambda * args, ** kwds: fn (fn .__ name__, * args, ** kwds)' (come eso, SO formatear los comentarios) Tendría que cambiar la función saber que está siendo envuelto (el nombre es el primer arg y self/cls viene en segundo lugar). –

1

Uso introspección con el módulo inspect .

import inspect 

class MyClass: 
    def foo(self): 
     print "My name is %s" % inspect.stack()[0][3] 
2

Las otras respuestas lo explican bastante bien, así que contribuyo con un ejemplo más concreto.

name.py

def foo(): 
    print "name in foo",__name__ 

foo() 
print "foo's name",foo.__name__ 
print "name at top",__name__ 

salida

name in foo __main__ 
foo's name foo 
name at top __main__ 

nombre2.py

import name 

salida

name in foo name 
foo's name foo 
name at top name 

Aviso cómo el __name__ se refiere a una función de propiedad del módulo? Que es __main__ si el módulo se ejecuta directamente, o el nombre del módulo si se importa.

Deberías haber topado con el fragmento if __name__=="__main__":.

Puede encontrar el relevant docs here, ir a verlos. ¡Buena suerte! :)

1

Eche un vistazo a the inspect module.

Probar:

>>> import inspect 
>>> def foo(): 
...  print inspect.getframeinfo(inspect.currentframe())[2] 
... 
>>> foo() 
foo 

o:

>>> def foo2(): 
...  print inspect.stack()[0][3] 
... 
>>> foo2() 
foo2 
Cuestiones relacionadas