No Python, sem usar o traceback
módulo, existe uma maneira de determinar o nome de uma função de dentro dessa função?
Digamos que eu tenho um módulo foo com uma barra de funções. Ao executar foo.bar()
, existe uma maneira de a barra saber o nome da barra? Ou melhor ainda, foo.bar
o nome?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
python
function
introspection
traceback
Roubar
fonte
fonte
traceback
. Nem mesmo os tempos de respostas e comentários parecem confirmar.Respostas:
Python não possui um recurso para acessar a função ou seu nome dentro da própria função. Foi proposto, mas rejeitado. Se você não quiser jogar com a pilha, use
"bar"
ou usebar.__name__
dependendo do contexto.O aviso de rejeição fornecido é:
fonte
inspect.currentframe()
é uma dessas maneiras.print(inspect.currentframe().f_code.co_name)
fonte
[1][3]
para obter o nome do chamador.print(inspect.currentframe().f_code.co_name)
ou para obter o nome do chamador:print(inspect.currentframe().f_back.f_code.co_name)
. Eu acho que deveria ser mais rápido, já que você não recupera uma lista de todos os quadros de pilha comoinspect.stack()
faz.inspect.currentframe().f_back.f_code.co_name
não trabalha com um método decorado enquantoinspect.stack()[0][3]
faz ...Existem algumas maneiras de obter o mesmo resultado:
Observe que as
inspect.stack
chamadas são milhares de vezes mais lentas que as alternativas:fonte
inspect.currentframe()
Parece um bom equilíbrio entre o tempo de execução e uso de membros privados0.100 usec
ou de0.199 usec
qualquer maneira - centenas de vezes mais rápido que as opções 1 e 2, comparável à opção 4 (embora Antony Hatchkins tenha encontrado a opção 3 três vezes mais rápida que a opção 4).sys._getframe().f_code.co_name
maisinspect.currentframe().f_code.co_name
simplesmente porque já importei osys
módulo. Essa é uma decisão razoável? (considerando que as velocidades parecem bastante semelhantes)Você pode obter o nome que foi definido usando a abordagem que @Andreas Jung mostra , mas esse pode não ser o nome com o qual a função foi chamada:
Se essa distinção é importante para você ou não, não posso dizer.
fonte
.func_name
. Vale lembrar que nomes de classes e funções em Python são uma coisa e variáveis referentes a elas são outra.Foo2()
imprimirFoo
. Por exemplo:Foo2 = function_dict['Foo']; Foo2()
. Nesse caso, Foo2 é um ponteiro de função para talvez um analisador de linha de comando.Eu queria uma coisa muito semelhante, porque queria colocar o nome da função em uma sequência de log que fosse em vários lugares no meu código. Provavelmente não é a melhor maneira de fazer isso, mas aqui está uma maneira de obter o nome da função atual.
fonte
f
quadro e oco
código. Eu não uso que tanto o melhor se apenas i, salvo que, em algum trecho :-)Eu mantenho esse útil utilitário por perto:
Uso:
fonte
Eu acho que
inspect
é a melhor maneira de fazer isso. Por exemplo:fonte
Encontrei um invólucro que escreverá o nome da função
Isso imprimirá
fonte
my_funky_name.__name__
. Você pode passar a função .__ name__ para a função como um novo parâmetro. func (* args, ** kwargs, meu_nome = func .__ nome__). Para obter o nome do decorador de dentro da sua função, acho que seria necessário usar o Inspecionar. Mas recebendo o nome da função de controlar a minha função dentro de minha função correndo ... bem que apenas soa como o início de uma bela meme :)Na verdade, isso é derivado das outras respostas à pergunta.
Aqui está a minha opinião:
A provável vantagem desta versão em relação ao uso do inspect.stack () é que ele deve ser milhares de vezes mais rápido [veja a postagem e os horários de Alex Melihoff sobre o uso de sys._getframe () versus o uso de inspect.stack ()].
fonte
print(inspect.stack()[0].function)
parece funcionar também (Python 3.5).fonte
Aqui está uma abordagem preparada para o futuro.
A combinação das sugestões de @ CamHart e @ Yuval com a resposta aceita do @ RoshOxymoron tem o benefício de evitar:
_hidden
e métodos potencialmente obsoletosEntão, acho que isso funciona bem com futuras versões do python (testadas em 2.7.3 e 3.3.2):
fonte
Teste:
Resultado:
fonte
Não sei por que as pessoas complicam:
fonte
No IDE, o código gera
fonte
Você pode usar um decorador:
fonte
__name__
atributo de uma função. O uso requer saber o que você está tentando obter, o que não me parece muito útil em casos simples em que as funções não são definidas em tempo real.Eu faço minha própria abordagem usada para chamar super com segurança dentro do cenário de herança múltipla (coloquei todo o código)
uso da amostra:
testando:
resultado:
Dentro de cada método decorado @with_name, você tem acesso a self .__ fname__ como o nome da função atual.
fonte
Recentemente, tentei usar as respostas acima para acessar a documentação de uma função a partir do contexto dessa função, mas como as perguntas acima estavam retornando apenas a string de nome, ela não funcionou.
Felizmente, encontrei uma solução simples. Se como eu, você deseja se referir à função em vez de simplesmente obter a string que representa o nome que pode aplicar eval () à string do nome da função.
fonte
Sugiro não confiar nos elementos da pilha. Se alguém usar seu código em contextos diferentes (intérprete python por exemplo), sua pilha mudará e quebrará seu índice ([0] [3]).
Eu sugiro que você algo assim:
fonte
Isso é muito fácil de realizar com um decorador.
fonte