Reputation: 735
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 get
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
Upvotes: 8
Views: 607
Reputation:
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"
Upvotes: 4
Reputation: 193716
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
Upvotes: 1
Reputation: 52371
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! :)
Upvotes: 2
Reputation: 101216
Use introspection with the inspect module.
import inspect
class MyClass:
def foo(self):
print "My name is %s" % inspect.stack()[0][3]
Upvotes: 1
Reputation: 38247
This does what you're after:
from inspect import currentframe, getframeinfo
class MyClass:
def foo(self):
print "My name is %s" % getframeinfo(currentframe())[2]
Upvotes: 11
Reputation: 4639
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__
Upvotes: -2
Reputation: 54882
__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.
Upvotes: 3