为什么这段Python代码在导入/编译时卡住但在命令行中正常工作?

4 投票
3 回答
8060 浏览
提问于 2025-04-15 12:20

我正在尝试用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 个回答

1

这可能不是直接的原因,但你很少会希望在导入时执行某些“功能”。通常,你应该定义一个函数,然后像这样调用它:

import mymodule
mymodule.run()

在导入时运行的“全局”代码通常应该仅限于导入其他模块、定义变量、定义函数和类等内容……

5

在导入模块的时候执行这种代码确实不是个好主意,虽然我不太确定为什么会卡住——可能是导入机制做了一些奇怪的事情,跟paramiko产生了不好的互动(可能和线程有关?)。无论如何,通常的解决办法是把功能放到一个函数里:

def my_expensive_function(args):
    pass

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

这样一来,单纯导入这个模块就不会做任何事情,但当你运行脚本的时候,就会用命令行给定的参数来执行这个函数。

0

不管怎么说,我只是用import来编译代码。把脚本变成一个函数似乎对这种应用来说是多此一举。

我找了找其他编译的方法,发现了:

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

这样生成了一个pyc文件,效果正如我所期望的那样。所以我学到的教训是,使用import来编译Python脚本并不是一个可靠的方法。

撰写回答