Por que o Python está executando meu módulo quando eu o importo e como eu o paro?


173

Estou desenvolvendo um programa Python que pode ser executado de duas maneiras: a primeira é chamar "python main.py", que solicita a entrada do usuário de maneira amigável e, em seguida, executa a entrada do usuário por meio do programa. A outra maneira é chamar "python batch.py -file- ", que repassará toda a coleta amigável de entradas e executará o valor de entrada de um arquivo inteiro através do programa de uma só vez.

O problema é que, quando executo "batch.py", ele importa algumas variáveis ​​/ métodos / etc de "main.py" e quando executa esse código:

import main

na primeira linha do programa, ele imediatamente erros porque tenta executar o código em "main.py".

Como posso impedir que o Python execute o código contido no módulo "principal" que estou importando?

Respostas:


251

Porque é assim que o Python funciona - palavras-chave como classe nãodef são declarações . Em vez disso, são declarações reais ao vivo que são executadas. Se eles não fossem executados, seu módulo estaria .. vazio :-)

De qualquer forma, a abordagem idiomática é:

# stuff to run always here such as class/def
def main():
    pass

if __name__ == "__main__":
   # stuff only to run when not called via 'import' here
   main()

Consulte Para que serve if __name__ == "__main__"?

No entanto, requer controle de origem sobre o módulo que está sendo importeditado.

Feliz codificação.


1
apenas para confirmar, seu comentário "coisas apenas para execução quando não são chamadas via 'import' aqui" implica que os comandos sejam escritos em main (), certo? Ou isso não importa?
— Goldname 16/07/19

@Goldname O código dentro da instrução if não será executado quando importado, mas a função principal por si só está definida e pronta para uso mesmo através de uma importação. Este módulo apenas executaria a função principal quando executada, e não a executaria se importada. Tudo depende do que você quer fazer. Se você não precisa dos comandos dentro de main em outro lugar, escreva-os de qualquer maneira dentro do if. Mas para mim parece mais arrumado.
— Felix

51

Devido à maneira como o Python funciona, é necessário executar seus módulos quando os importar.

Para impedir que o código no módulo seja executado quando importado, mas apenas quando executado diretamente, você pode protegê-lo com isso if:

if __name__ == "__main__":
    # this won't be run when imported

Você pode colocar esse código em um main()método, para poder executar o arquivo diretamente ou importar o módulo e chamar o main(). Por exemplo, suponha que isso esteja no arquivo foo.py.

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

Este programa pode ser executado indo python foo.pyou a partir de outro script Python:

import foo

...

foo.main()

12

Use o if __name__ == '__main__'idioma - __name__é uma variável especial cujo valor é '__main__'se o módulo estiver sendo executado como um script e o nome do módulo se for importado. Então você faria algo como

# imports
# class/function definitions
if __name__ == '__main__':
    # code here will only run when you invoke 'python main.py'

4

Infelizmente você não. Isso faz parte de como a sintaxe de importação funciona e é importante que isso aconteça - lembre- defse de que na verdade é algo executado, se o Python não executasse a importação, você ficaria preso às funções.

Porém, como você provavelmente tem acesso ao arquivo, poderá procurar e ver o que causa o erro. Pode ser possível modificar seu ambiente para impedir que o erro aconteça.


1
Como uma nota: se não há nenhuma maneira de modificar o ambiente para que o erro pode ser evitado, talvez você deve usar um módulo diferente
— cwallenpoole

4

Coloque o código dentro de uma função e ele não será executado até que você chame a função. Você deve ter uma função principal no seu main.py. com a declaração:

if __name__ == '__main__':
  main()

Então, se você chamar, python main.pya main()função será executada. Se você importar main.py, não será. Além disso, você provavelmente deve renomear main.pypara outra coisa por uma questão de clareza.


3

Havia uma proposta de aprimoramento do Python PEP 299 que visava substituir o if __name__ == '__main__':idioma por def __main__:, mas foi rejeitada. Ainda é uma boa leitura saber o que ter em mente ao usar if __name__ = '__main__':.


2

Você pode escrever seu "main.py" assim:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()

-1

Embora você não possa usar importsem executar o código; existe uma maneira rápida de inserir suas variáveis; usando numpy.savez, que armazena variáveis ​​como matrizes numpy em um arquivo .npz. Depois, você pode carregar as variáveis ​​usando numpy.load.

Veja uma descrição completa na documentação do scipy

Observe que este é apenas o caso de variáveis ​​e matrizes de variáveis, e não de métodos etc.


-4

Tente apenas importar as funções necessárias do main.py? Assim,

from main import SomeFunction

Pode ser que você tenha nomeado uma função em batch.py ​​da mesma forma que uma em main.py, e quando você importa main.py, o programa executa a função main.py em vez da função batch.py; fazendo o acima deve corrigir isso. Eu espero.


Pelo menos no Windows, não.
— Martín Coll

2
import mainNÃO importa tudo do main para o namespace atual. Ele adiciona apenas um único mainsímbolo no espaço para nome atual, para que colisões não possam acontecer.
— Remor #
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.