2010-02-08 5 views
8

że mam następujące klasy zdefiniowanej metodą foo:Jak odwołać się do nazwy metody z za pomocą metody w Pythonie?

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

Teraz gdy zgłoszę foo() Spodziewam/chcą zobaczyć ten wydrukowane

My name is foo 

Jednak mam

My name is __main__ 

A jeśli mam umieścić definicję klasy w module o nazwie FooBar, otrzymam

My name is FooBar 

Jednak jeśli mam

m = MyClass() 
print m.foo.__name__ 

dostać dokładnie to, co chcę, co jest

My name is foo 

Czy ktoś może pomóc wyjaśnić dlaczego __name__ odnosi się do modułu, a nie nazwą metoda? Czy istnieje łatwy sposób uzyskania nazwy metody?

Dziękujemy

+0

dlaczego trzeba to zrobić? z jakim problemem rozwiązujesz? – SilentGhost

Odpowiedz

4

Nazwy zawsze odnoszą się do zmiennych lokalnych lub (jeśli nie istnieje), a następnie zmiennych globalnych. Istnieje globalna nazwa ___, która ma nazwę modułu.

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

Oczywiście, jest to zbędne i prawie całkowicie bezcelowe. Wystarczy wpisać się nazwę metody:

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

Dlaczego upadek? –

+0

Może to być konkurencyjne uderzenie. To mi się przydarzyło. – Skurmedel

+1

@Skurmedel: To zawsze jest możliwe i boli bardziej niż mnie (przez awanse w odpowiedzi to dla mnie wygrana netto, nawet do gry), ale jeśli coś przeoczyłem, naprawdę chcę o tym wiedzieć. –

-1

to zrobi:

(. Trzeba odwołać się do self.__class__._name__)

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

Pożądane zachowanie, jak pokazano w tym przykładzie drukuje "foo" (nazwa metody), a nie "MyClass". –

+0

Doh, racja, nie przeczytał dokładnie tego pytania. – 0xfe

11

to robi to, co jesteś po:


from inspect import currentframe, getframeinfo 

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

Chociaż jest to poprawne, nie ma powodu, aby preferować go po prostu wpisując "foo" w treści funkcji bez większej ilości informacji z PO. –

+0

Fajnie, zastanawiam się, czy można zrobić dekoratora, który robi to jakoś ... Przynajmniej po tym, jak została ułożona metoda dekorowania. Może mógłbyś sprawdzić dekorowaną metodę. – Skurmedel

+0

@Skurmedel: 'def with_name (fn): return lambda * args, ** kwds: fn (fn .__ name__, * args, ** kwds)' (zjedz to, formatowanie komentarza SO) Musiałbyś zmienić funkcję wiedzieć, że jest zapakowany (nazwa jest pierwszym argem, a self/cls jest drugi). –

1

użytkowania introspekcji z modułem inspect .

import inspect 

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

Inne odpowiedzi wyjaśniają to całkiem dobrze, więc przyczyniam się do bardziej konkretnego przykładu.

name.py

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

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

Wyjście

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

name2.py

import name 

Wyjście

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

Wskazówki jak __name__ odnosi się do wbudowanej własności modułu? Który jest __main__, jeśli moduł jest uruchamiany bezpośrednio, lub nazwa modułu, jeśli jest importowana.

Powinieneś był przejść przez fragment kodu if __name__=="__main__":.

Możesz znaleźć relevant docs here, sprawdź je. Powodzenia! :)

1

Spójrz na the inspect module.

Spróbuj:

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

czyli

>>> def foo2(): 
...  print inspect.stack()[0][3] 
... 
>>> foo2() 
foo2 
Powiązane problemy