Suponha que eu tenha uma função Python conforme definida abaixo:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
Eu posso obter o nome da função usando foo.func_name
. Como obtenho programaticamente seu código fonte, conforme digitei acima?
foo.__name__
Respostas:
Se a função for de um arquivo de origem disponível no sistema de arquivos,
inspect.getsource(foo)
poderá ser útil :Se
foo
é definido como:Então:
Devoluções:
Mas acredito que, se a função for compilada a partir de uma string, fluxo ou importada de um arquivo compilado, você não poderá recuperar seu código-fonte.
fonte
len
. Onde posso encontrar o código fonte dalen
função?inspect.getsourcelines(foo)
O módulo inspecionar possui métodos para recuperar o código-fonte de objetos python. Aparentemente, só funciona se a fonte estiver localizada em um arquivo. Se você tivesse isso, acho que não precisaria obter a fonte do objeto.
fonte
python 3.5.3
intérprete.import inspect
+inspect.getsource(foo)
funcionou bem.dis
é seu amigo se o código fonte não estiver disponível:fonte
Se você estiver usando IPython, precisará digitar "foo ??"
fonte
dir(MyClass)
entãoMyClass.__init__??
e assim por diante.Embora eu concorde geralmente que essa
inspect
é uma boa resposta, discordo que você não pode obter o código fonte dos objetos definidos no intérprete. Se você usardill.source.getsource
fromdill
, poderá obter a fonte de funções e lambdas, mesmo se elas estiverem definidas interativamente. Ele também pode obter o código de métodos e funções de classe vinculados ou não definidos definidos em curries ... no entanto, talvez você não consiga compilar esse código sem o código do objeto que o encerra.fonte
dill.source.getsource
inspeciona o histórico do intérprete em busca de funções, classes, lambdas etc. - ele não inspeciona o conteúdo das seqüências de caracteres transmitidas ao exec.dill
para responder a esta pergunta: stackoverflow.com/questions/13827543/…dill.source
tem funções comogetname
eimportable
egetsource
que o foco em obter o código fonte (ou um importable que os rendimentos do objeto) para um determinado objeto. Para coisas simples como um,int
não há fonte, portanto não funciona como esperado (por exemplo, para 'a = 10', retorna '10').>>> a = 10; print( [key for key, val in globals().items() if val is a][0] )
dill
, mas minha resposta deixa um pouco a desejar (ou seja, se você tiver vários nomes para o mesmo valor, não será possível descobrir qual foi usado. passar uma expressão, ela não pode dizer o que era essa expressão.Heck, se você passar uma expressão que é avaliada da mesma forma que um nome, ela fornecerá esse nome.) Podedill
resolver qualquer uma dessas deficiências da minha resposta aqui: stackoverflow.com/a/28634996/901641Para expandir a resposta de runeh:
EDIT: Como apontado por @ 0sh, este exemplo funciona usando,
ipython
mas não é simplespython
. No entanto, deve ser bom para ambos quando importar código de arquivos de origem.fonte
getsource(foo)
.Você pode usar o
inspect
módulo para obter o código fonte completo para isso. Você precisa usar ogetsource()
método para isso noinspect
módulo. Por exemplo:Você pode conferir mais opções no link abaixo. recuperar seu código python
fonte
Como este post está marcado como duplicado deste outro post , respondo aqui pelo caso "lambda", embora o OP não seja sobre lambdas.
Portanto, para funções lambda que não são definidas em suas próprias linhas: além da resposta de marko.ristin , você pode usar o mini-lambda ou o SymPy, conforme sugerido nesta resposta .
mini-lambda
é mais leve e suporta qualquer tipo de operação, mas funciona apenas para uma única variávelSymPy
é mais pesado, mas muito mais equipado com operações matemáticas / de cálculo. Em particular, pode simplificar suas expressões. Ele também suporta várias variáveis na mesma expressão.Aqui está como você pode fazer isso usando
mini-lambda
:Produz corretamente
Consulte a
mini-lambda
documentação para obter detalhes. Eu sou o autor, a propósito;)fonte
Lembre-se de que as respostas aceitas funcionam apenas se o lambda for fornecido em uma linha separada. Se você o passar como argumento para uma função e desejar recuperar o código do lambda como objeto, o problema será um pouco complicado, pois
inspect
fornecerá toda a linha.Por exemplo, considere um arquivo
test.py
:A execução dá a você (preste atenção à indentação!):
Para recuperar o código fonte do lambda, sua melhor aposta, na minha opinião, é analisar novamente o arquivo fonte inteiro (usando
f.__code__.co_filename
) e corresponder o nó AST lambda pelo número da linha e seu contexto.Tivemos que fazer exatamente isso em nosso contrato de icon -library por contrato de design, pois tivemos que analisar as funções lambda que passamos como argumentos para os decoradores. É muito código para colar aqui, então dê uma olhada na implementação desta função .
fonte
Se você mesmo estiver definindo estritamente a função e for uma definição relativamente curta, uma solução sem dependências seria definir a função em uma string e atribuir o eval () da expressão à sua função.
Por exemplo
opcionalmente, para anexar o código original à função:
fonte
para resumir:
fonte
Eu acredito que os nomes de variáveis não são armazenados na PYC / PYD / pyo arquivos, para que você não pode recuperar as linhas de código exato, se você não tem arquivos de origem.
fonte