Почему этот код Python зависает при импорте / компиляции, но работает в оболочке?
-
06-07-2019 - |
Вопрос
Я пытаюсь использовать 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
Помимо странностей, я просто использовал импорт для компиляции кода. Превращение скрипта в функцию кажется ненужным усложнением для такого рода приложений.
Искал альтернативные средства для компиляции и нашел:
import py_compile py_compile.compile("ProblemDemo.py")
Это сгенерировало pyc-файл, который работает как задумано. Таким образом, извлеченный урок заключается в том, что импорт не является надежным способом компиляции сценариев Python.
Другие советы
Это действительно плохая идея для выполнения такого рода кода во время импорта, хотя я не уверен, почему он зависает - возможно, механизм импорта делает что-то странное, что плохо взаимодействует с paramiko (могут быть проблемы, связанные с потоками?). В любом случае, обычным решением является внедрение функциональности в функцию:
def my_expensive_function(args):
pass
if __name__ == '__main__':
import sys
my_expensive_functions(sys.args)
Таким образом, простой импорт модуля ничего не изменит, но выполнение скрипта выполнит функцию с заданными аргументами в командной строке.
Это не может быть прямой причиной, но редко вы когда-либо хотели бы иметь " функциональность " выполнено при импорте. Обычно вы должны определить класс или функцию , которую затем вызываете так:
import mymodule
mymodule.run()
" глобальный " код, который вы запускаете при импорте, обычно должен быть ограничен импортом, определениями переменных, определениями функций и классов и т. п. ...