【问题标题】:Why does this python code hang on import/compile but work in the shell?为什么此 python 代码在导入/编译时挂起但在 shell 中工作?
【发布时间】:2009-06-18 14:45:19
【问题描述】:

我正在尝试使用 python 来 sftp 文件,并且代码在交互式 shell 中运行良好 - 甚至可以一次将其全部粘贴。

当我尝试导入文件(只是为了编译它)时,代码挂起,没有异常或明显错误。

我如何让代码编译,或者是否有人有通过其他方法完成 sftp 的工作代码?

这段代码直接挂在 ssh.connect() 语句处:

""" 问题演示.py 从 paramiko 演示文件中删除。 此代码在 shell 中工作,但当我尝试导入它时挂起! """ 从时间导入睡眠 导入操作系统 进口帕拉米科 sOutputFilename = "redacted.htm" #-- 有效负载文件 主机名 = "redacted.com" #### - 警告!嵌入式密码!尽快删除。 sUsername = "已编辑" sPassword = "已编辑" sTargetDir = "已编辑" #-- 获取主机密钥,如果我们知道的话。 主机键类型 = 无 主机键 = 无 主机键 = {} 尝试: host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) 除了 IOError: 尝试: # 也试试 ~/ssh/,因为 windows 不能有一个名为 ~/.ssh/ 的文件夹 host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts')) 除了 IOError: print '*** 无法打开主机密钥文件' 主机键 = {} 如果 host_keys.has_key(主机名): hostkeytype = host_keys[主机名].keys()[0] hostkey = host_keys[hostname][hostkeytype] print '使用类型为 %s 的主机密钥' % hostkeytype ssh = paramiko.Transport((主机名, 22)) ssh.connect(用户名=s用户名,密码=s密码,主机密钥=主机密钥) sftp = paramiko.SFTPClient.from_transport(ssh) sftp.chdir(目标目录) sftp.put (sOutputFilename, sOutputFilename) ssh.close()

【问题讨论】:

标签: python shell compilation sftp


【解决方案1】:

在导入时执行这种代码确实是个坏主意,尽管我不确定它为什么会挂起 - 可能是导入机制做了一些奇怪的事情,与 paramiko 交互不好(可能是线程相关问题?)。无论如何,通常的解决方案是将功能实现为函数:

def my_expensive_function(args):
    pass

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

这样,仅仅导入模块不会做任何事情,但是运行脚本会在命令行中执行带有给定参数的函数。

【讨论】:

  • +1 查看详细分析here。我同意最小化在import 时间执行的代码(尤其是等待)将有助于避免该问题。
【解决方案2】:

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

import mymodule
mymodule.run()

您在导入中运行的“全局”代码通常应仅限于导入、变量定义、函数和类定义等......

【讨论】:

  • 如何从操作系统运行这样的文件?这不是一个库,我只是导入它来获取生成的 pyc 文件。
【解决方案3】:

除了奇怪之外,我只是使用 import 来编译代码。将脚本转换为函数似乎对这种应用程序来说是不必要的复杂化。

搜索替代方法编译发现:

导入 py_compile py_compile.compile("ProblemDemo.py")

这会生成一个按预期工作的 pyc 文件。 所以吸取的教训是 import 不是编译 python 脚本的可靠方法。

【讨论】:

  • 但是你为什么要首先编译你的python脚本呢?
  • 它可以更轻松地从 Windows 资源管理器和 Windows 任务调度程序运行。
  • 我认为正确的教训是在导入期间不要运行冗长或复杂的代码。也许它是“合法的”,但在许多层面上肯定是不明智的。
  • 那是一个课,但这里真正的课是它的推论:不要使用导入来编译临时脚本。这个问题的目标是成功编译。像我一样的菜鸟被告知要使用 import 来获取编译后的文件——它已经在许多脚本上工作——但这​​是一个糟糕的建议。
  • 我想你误解了这里发生了什么。 Python 不是一种编译语言。导入模块时不应运行重要代码;而是将其包装在一个函数中。
猜你喜欢
  • 1970-01-01
  • 2022-08-08
  • 2021-09-29
  • 2019-12-26
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多