Suponha que myapp/foo.py
contém:
def info(msg):
caller_name = ????
print '[%s] %s' % (caller_name, msg)
E myapp/bar.py
contém:
import foo
foo.info('Hello') # => [myapp.bar] Hello
Eu quero caller_name
ser definido para o __name__
atributo do módulo de funções de chamada (que é 'myapp.foo') neste caso. Como isso pode ser feito?
python
stack-trace
introspection
Sridhar Ratnakumar
fonte
fonte
caller_name
não pode ser__main__
Respostas:
Confira o módulo de inspeção:
inspect.stack()
retornará as informações da pilha.Dentro de uma função,
inspect.stack()[1]
retornará a pilha do chamador. A partir daí, você pode obter mais informações sobre o nome da função do chamador, módulo, etc.Consulte a documentação para obter detalhes:
http://docs.python.org/library/inspect.html
Além disso, Doug Hellmann tem uma boa descrição do módulo de inspeção em sua série PyMOTW:
http://pymotw.com/2/inspect/index.html#module-inspect
EDIT: Aqui está um código que faz o que você quer, eu acho:
fonte
__name__
atributo deste módulo usando oinspect
módulo? Por exemplo, como faço para voltarmyapp.foo
(nãomyapp/foo.py
) no meu exemplo acima? Já tentei usar o módulo inspect antes de postar no SO.inspect.stack()[2]
para o chamador real.Confrontado com um problema semelhante, descobri que sys._current_frames () do módulo sys contém informações interessantes que podem ajudá-lo, sem a necessidade de importar inspecionar, pelo menos em casos de uso específicos.
Você pode então "subir" usando f_back:
Para o nome do arquivo, você também pode usar f.f_back.f_code.co_filename, conforme sugerido por Mark Roddy acima. Não tenho certeza dos limites e advertências desse método (vários threads provavelmente serão um problema), mas pretendo usá-lo no meu caso.
fonte
sys._getframe(1)
, em vez de chamarsys._current_frames()
(btw que retorna um mapeamento de quadro para cada thread).inspect.currentframe()
vez desys._current_frames().values()[0]
.Não recomendo fazer isso, mas você pode alcançar seu objetivo com o seguinte método:
Em seguida, atualize seu método existente da seguinte maneira:
fonte
__name__