Por que esse código python pendurar na importação / compilação, mas trabalho no shell?
-
06-07-2019 - |
Pergunta
Eu estou tentando usar python para sftp um arquivo, eo código funciona muito bem no shell interativo -. Mesmo colá-lo em uma só vez
Quando tento importar o arquivo (apenas para compilá-lo), os trava de código sem exceções ou erros óbvios.
Como faço para obter o código para compilar, ou alguém tem código de trabalho que realiza sftp por algum outro método?
Este código trava direita na declaração ssh.connect ():
""" ProblemDemo.py Chopped down from the paramiko demo file. This code works in the shell but hangs when I try to import it! """ from time import sleep import os import paramiko sOutputFilename = "redacted.htm" #-- The payload file hostname = "redacted.com" ####-- WARNING! Embedded passwords! Remove ASAP. sUsername = "redacted" sPassword = "redacted" sTargetDir = "redacted" #-- Get host key, if we know one. hostkeytype = None hostkey = None host_keys = {} try: host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) except IOError: try: # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/ host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts')) except IOError: print '*** Unable to open host keys file' host_keys = {} if host_keys.has_key(hostname): hostkeytype = host_keys[hostname].keys()[0] hostkey = host_keys[hostname][hostkeytype] print 'Using host key of type %s' % hostkeytype ssh = paramiko.Transport((hostname, 22)) ssh.connect(username=sUsername, password=sPassword, hostkey=hostkey) sftp = paramiko.SFTPClient.from_transport(ssh) sftp.chdir (sTargetDir) sftp.put (sOutputFilename, sOutputFilename) ssh.close()
Solução 3
Weirdness lado, eu estava apenas usando importação para compilar o código. Virando o script em uma função parece ser uma complicação desnecessária para este tipo de aplicação.
Procurou por meios alternativos para compilar e encontrado:
import py_compile py_compile.compile("ProblemDemo.py")
Esta gerado um arquivo pyc que funciona como pretendido. Assim, a lição aprendida é que a importação não é uma maneira robusta de scripts python de compilação.
Outras dicas
Isso é realmente uma má idéia para executar este tipo de código em tempo de importação, embora eu não estou certo porque ele trava - pode ser que mecanismo de importação faz algo estranho que interage mal com paramiko (questões de rosca relacionado talvez?). De qualquer forma, a solução usual é a de implementar a funcionalidade em uma função:
def my_expensive_function(args):
pass
if __name__ == '__main__':
import sys
my_expensive_functions(sys.args)
Desta forma, apenas importando o módulo não vai fazer nada, mas executar o script irá executar a função com os argumentos fornecidos na linha de comando.
Isto não pode ser uma razão direta porquê, mas raramente você nunca querem ter "funcionalidade" executado na importação. Normalmente, você deve definir um class ou função que você, em seguida, chamar assim:
import mymodule
mymodule.run()
O código "global" que correr em uma importação normalmente deve ser limitado às importações, as definições das variáveis, função e definições de classe, e assim por diante ...