Почему этот код Python зависает при импорте / компиляции, но работает в оболочке? - PullRequest
1 голос
/ 18 июня 2009

Я пытаюсь использовать python для sftp файла, и код отлично работает в интерактивной оболочке - даже вставляя его сразу.

Когда я пытаюсь импортировать файл (просто для его компиляции), код зависает без исключений и явных ошибок.

Как мне получить код для компиляции, или у кого-то есть рабочий код, который выполняет sftp другим методом?

Этот код висит прямо в операторе 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()

Ответы [ 3 ]

4 голосов
/ 18 июня 2009

Это действительно плохая идея для выполнения такого рода кода во время импорта, хотя я не уверен, почему он зависает - возможно, механизм импорта делает что-то странное, что плохо взаимодействует с paramiko (могут быть проблемы с потоками?) В любом случае, обычным решением является внедрение функциональности в функцию:

def my_expensive_function(args):
    pass

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

Таким образом, простой импорт модуля ничего не даст, но запуск скрипта выполнит функцию с заданными аргументами в командной строке.

1 голос
/ 18 июня 2009

Возможно, это не является прямой причиной, но редко вы когда-либо хотите, чтобы "функциональность" выполнялась при импорте. Обычно вы должны определить class или function , которую вы затем вызываете так:

import mymodule
mymodule.run()

«Глобальный» код, который вы запускаете при импорте, обычно должен быть ограничен импортом, определениями переменных, определениями функций и классов и т. П. ...

0 голосов
/ 18 июня 2009

Странно, я просто использовал импорт для компиляции кода. Превращение скрипта в функцию кажется ненужным осложнением для такого рода приложений.

Искал альтернативные средства для компиляции и нашел:

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

Это сгенерировало pyc-файл, который работает как задумано. Таким образом, извлеченный урок заключается в том, что импорт не является надежным способом компиляции скриптов Python.

...