How to refer to a method name from with a method in Python?
Say I have the following class defined with the method foo
:
class MyClass:
def foo(self):
print "My name is %s" % __name__
Now when I call foo()
I expect/want to see this printed out
My name is foo
However I get
My name is __main__
And if I was to put the class definition into a module called FooBar
I would ge开发者_Go百科t
My name is FooBar
However if I do
m = MyClass()
print m.foo.__name__
I get exactly what I want which is
My name is foo
Can someone please help explain why __name__
refers to the module and not the method name ?
Is there an easy way to get the method name?
Many thanks
This does what you're after:
from inspect import currentframe, getframeinfo
class MyClass:
def foo(self):
print "My name is %s" % getframeinfo(currentframe())[2]
Names always refer to local variables or (if one doesn't exist) then global variables. There is a a global __name__ that has the module's name.
class MyClass:
def foo(self):
print "My name is %s" % MyClass.foo.__name__
Of course, that's redundant and almost entirely pointless. Just type out the method name:
class MyClass:
def foo(self):
print "My name is %s" % "foo"
print "My name is foo"
__name__
refers to the module because that's what it's supposed to do. The only way to get at the currently running function would be to introspect the stack.
The other answers explain it quite well so I contribute with a more concrete example.
name.py
def foo():
print "name in foo",__name__
foo()
print "foo's name",foo.__name__
print "name at top",__name__
Output
name in foo __main__
foo's name foo
name at top __main__
name2.py
import name
Output
name in foo name
foo's name foo
name at top name
Notice how the __name__
refers to built-in property of the module? Which is __main__
if the module is run directly, or the name of the module if its imported.
You should have run across the if __name__=="__main__":
snippet.
You can find the relevant docs here, go check them out. Good luck! :)
Use introspection with the inspect module.
import inspect
class MyClass:
def foo(self):
print "My name is %s" % inspect.stack()[0][3]
Have a look at the the inspect
module.
Try:
>>> import inspect
>>> def foo():
... print inspect.getframeinfo(inspect.currentframe())[2]
...
>>> foo()
foo
or:
>>> def foo2():
... print inspect.stack()[0][3]
...
>>> foo2()
foo2
This will do it:
(You need to refer to self.__class__._name__
.)
class MyClass:
def foo(self):
print "My name is %s" % self.__class__.__name__
精彩评论