Как сослаться на имя метода из метода в Python? - PullRequest
8 голосов
/ 08 февраля 2010

Скажем, у меня есть следующий класс, определенный с помощью метода foo:

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

Теперь, когда я звоню foo() Я ожидаю / хочу увидеть это распечатанным

My name is foo  

Однако я получаю

My name is __main__  

И если бы я поместил определение класса в модуль с именем FooBar, я бы получил

My name is FooBar  

Однако, если я сделаю

m = MyClass()
print m.foo.__name__

Я получаю именно то, что хочу,

My name is foo

Может кто-нибудь помочь объяснить, почему __name__ относится к модулю, а не к имени метода? Есть ли простой способ получить имя метода?

Большое спасибо

Ответы [ 7 ]

11 голосов
/ 08 февраля 2010

Это делает то, что вы после:


from inspect import currentframe, getframeinfo

class MyClass:
    def foo(self):
        print "My name is %s" % getframeinfo(currentframe())[2]
4 голосов
/ 08 февраля 2010

Имена всегда ссылаются на локальные переменные или (если их нет) глобальные переменные. Существует глобальное __name__ с именем модуля.

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

Конечно, это избыточно и почти совершенно бессмысленно. Просто введите название метода:

class MyClass:
  def foo(self):
    print "My name is %s" % "foo"
    print "My name is foo"
3 голосов
/ 08 февраля 2010

__name__ относится к модулю, потому что это то, что он должен делать . Единственный способ получить доступ к текущей выполняемой функции - это проанализировать стек.

2 голосов
/ 08 февраля 2010

Другие ответы объясняют это довольно хорошо, поэтому я привожу более конкретный пример.

name.py

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

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

выход

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

name2.py

import name

выход

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

Обратите внимание, как __name__ относится к встроенному свойству модуля? Это __main__, если модуль запускается напрямую, или имя модуля, если он импортирован.

Вы должны были наткнуться на фрагмент if __name__=="__main__":.

Вы можете найти соответствующие документы здесь , посмотрите их. Удачи! :)

1 голос
/ 08 февраля 2010

Посмотрите на модуль inspect .

Попробуйте:

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

или

>>> def foo2():
...     print inspect.stack()[0][3]
...
>>> foo2()
foo2
1 голос
/ 08 февраля 2010

Используйте самоанализ с модулем inspect .

import inspect

class MyClass:
    def foo(self):
        print "My name is %s" % inspect.stack()[0][3]
0 голосов
/ 08 февраля 2010

Это сделает это:

(Вам необходимо обратиться к self.__class__._name__.)

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