¿Por qué este código de Python se bloquea en la importación / compilación pero funciona en el shell?

StackOverflow https://stackoverflow.com/questions/1013064

Pregunta

Estoy tratando de usar python para procesar un archivo, y el código funciona muy bien en el shell interactivo, incluso pegándolo todo de una vez.

Cuando intento importar el archivo (solo para compilarlo), el código se cuelga sin excepciones ni errores obvios.

¿Cómo obtengo el código para compilar, o alguien tiene un código de trabajo que logra sftp por algún otro método?

Este código se cuelga justo en la declaración 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()

¿Fue útil?

Solución 3

Dejando de lado la rareza, solo estaba usando import para compilar el código. Convertir el script en una función parece una complicación innecesaria para este tipo de aplicación.

Buscó medios alternativos para compilar y encontró:

import py_compile
py_compile.compile("ProblemDemo.py")

Esto generó un archivo pyc que funciona según lo previsto. Entonces, la lección aprendida es que la importación no es una forma sólida de compilar scripts de Python.

Otros consejos

De hecho, es una mala idea ejecutar este tipo de código en el momento de la importación, aunque no estoy seguro de por qué se cuelga; puede ser que el mecanismo de importación haga algo extraño que interactúe mal con paramiko (¿quizás problemas relacionados con hilos?). De todos modos, la solución habitual es implementar la funcionalidad en una función:

def my_expensive_function(args):
    pass

if __name__ == '__main__':
    import sys
    my_expensive_functions(sys.args)

De esta manera, solo importar el módulo no hará nada, pero ejecutar el script ejecutará la función con los argumentos dados en la línea de comando.

Puede que esta no sea una razón directa, pero rara vez quiere tener "funcionalidad". ejecutado a la importación. Normalmente, debe definir una clase o función que luego llamará así:

import mymodule
mymodule.run()

El " global " el código que ejecuta en una importación normalmente debe limitarse a importaciones, definiciones de variables, definiciones de funciones y clases, y similares ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top