Declarar função no final do arquivo em Python

92

É possível chamar uma função sem primeiro defini-la totalmente? Ao tentar fazer isso, recebo o erro: " function_name is not defined". Eu estou vindo de uma experiência em C ++, então esse problema me deixa perplexo.

Declarando a função antes de funcionar:

def Kerma():
        return "energy / mass"    

print Kerma()

No entanto, tentar chamar a função sem primeiro defini-la dá problemas:

print Kerma()

def Kerma():
    return "energy / mass"

Em C ++, você pode declarar uma função após a chamada, uma vez que você coloque seu cabeçalho antes dela.

Estou faltando alguma coisa aqui?

TheGentleOne
fonte
5
Em Python não há "declarar". Existe a definição (que deve ser completa) ou não há nada.
S.Lott de
2
Você diz, "dá problemas". Você pode elaborar sobre isso?
Martin Del Vecchio de
Possível duplicata de funções
usuário
Caso alguém esteja se perguntando:Kerma is an acronym for "kinetic energy released per unit mass"
anon
1
Eu sei que isso é muito antigo, mas por que ninguém recomendou colocar as funções em um .pyarquivo separado e importá-lo? Existem algumas consequências indesejadas?
Kyle

Respostas:

144

Uma maneira que é meio idiomática em Python é escrevendo:

def main():
    print Kerma()

def Kerma():
    return "energy / mass"    

if __name__ == '__main__':
    main()

Isso permite que você escreva o código na ordem que desejar, desde que continue chamando a função mainno final.

Muhammad Alkarouri
fonte
4
@Muhammad: embora seja uma abordagem viável, certamente não é idiomática em Python. Muito pelo contrário, você notará que a maioria das mainfunções geralmente são colocadas no final.
Eli Bendersky de
14
@Eli Bendersky: Eu diria que a if __name__ == '__main__':mudança é a parte idiomática comum.
S.Lott de
2
@Eli: a parte idiomática é a cláusula if no final: nenhum código no nível superior do módulo, então, no final, invoque uma função principal se o módulo for principal .
Ned Batchelder de
1
@Eli: A parte idiomática é o if ... __main__':. Eu não disse que o maindeveria ser colocado acima do resto do código. Eu disse que a parte importante é chamar _\_main__no final, e não importa onde você coloque sua definição então.
Muhammad Alkarouri de
2
Com o switch if name == ' main ': torna-se irrelevante como você ordena suas funções. Essa é a coisa certa (TM) a fazer.
MKesper
18

Quando um módulo Python (arquivo .py) é executado, as instruções de nível superior nele são executadas na ordem em que aparecem, de cima para baixo (do começo ao fim). Isso significa que você não pode fazer referência a algo até que tenha definido. Por exemplo, o seguinte irá gerar o erro mostrado:

c = a + b  # -> NameError: name 'a' is not defined
a = 13
b = 17

Ao contrário de muitas outras linguagens, defe as classinstruções são executáveis ​​em Python - não apenas declarativas - portanto, você não pode fazer referência a nenhum dos dois aou baté que isso aconteça e sejam definidos. É por isso que seu primeiro exemplo tem problemas - você está referenciando a Kerma()função antes de sua definstrução ser executada e o corpo ter sido processado e o objeto de função resultante vinculado ao nome da função, portanto, não está definido nesse ponto do script.

Programas em linguagens como C ++ são geralmente pré-processados ​​antes de serem executados e durante este estágio de compilação, o programa inteiro e quaisquer #includearquivos aos quais ele se refere são lidos e processados ​​de uma vez. Ao contrário do Python, esta linguagem apresenta instruções declarativas que permitem que o nome e a sequência de chamada das funções (ou tipo estático de variáveis) sejam declarados (mas não definidos), antes de usar para que, quando o compilador encontrar seu nome, tenha informações suficientes para verificar seus uso, que envolve principalmente a verificação de tipo e conversões de tipo, nenhuma das quais requer que seu conteúdo real ou corpos de código tenham sido definidos ainda.

martineau
fonte
Não é que uma linguagem dinâmica não possa fazer isso. Perl é uma linguagem dinâmica e você pode chamar uma função antes de defini-la. Isso porque ele tem uma fase de compilação e uma fase de execução (embora estranhamente, mas útil, você pode organizar a execução do código durante a fase de compilação). Isso funciona: doit(); sub doit { print("I'm doing it!\n"); }
John Deighan
10

Isso não é possível em Python, mas, francamente, você logo descobrirá que não precisa disso. A maneira Pythônica de escrever código é dividir seu programa em módulos que definem classes e funções, e um único "módulo principal" que importa todos os outros e executa.

Para scripts simples descartáveis, acostume-se a colocar a "parte executável" no final ou, melhor ainda, aprenda a usar um shell Python interativo.

Eli Bendersky
fonte
1

Python é uma linguagem dinâmica e o interpretador sempre pega o estado das variáveis ​​(funções, ...) como elas estão no momento de chamá-las. Você pode até redefinir as funções em alguns blocos if e chamá-los de maneira diferente a cada vez. É por isso que você deve defini-los antes de chamá-los.

eumiro
fonte