Why does this python code hang on import/compile but work in the shell?
我尝试使用python来sftp一个文件,代码在交互式shell中工作得很好——甚至可以同时粘贴它。
当我试图导入文件(只是为了编译它)时,代码挂起,没有异常或明显的错误。
如何让代码进行编译,或者某人是否有通过其他方法完成sftp的工作代码?
此代码正好挂在ssh.connect()语句上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | """ 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() |
在导入时执行这种代码确实是一个坏主意,尽管我不确定它为什么挂起——可能是导入机制做了一些奇怪的事情,它与Paramiko(线程相关的问题,可能是吗?)。无论如何,通常的解决方案是将功能实现为一个函数:
1 2 3 4 5 6 | def my_expensive_function(args): pass if __name__ == '__main__': import sys my_expensive_functions(sys.args) |
这样,只导入模块不会做任何事情,但运行脚本将在命令行使用给定参数执行函数。
这可能不是一个直接的原因,但很少有人希望在导入时执行"功能"。通常,您应该定义一个类或函数,然后这样调用它:
1 2 | import mymodule mymodule.run() |
在导入中运行的"全局"代码通常应限于导入、变量定义、函数和类定义等…
奇怪的是,我只是用import来编译代码。对于这种应用程序来说,将脚本转换为函数似乎是不必要的复杂操作。
寻找替代手段编译并发现:
1 2 | import py_compile py_compile.compile("ProblemDemo.py") |
这生成了一个按预期工作的pyc文件。因此,我们学到的经验是,导入并不是编译Python脚本的可靠方法。