Spyder:如何在本地编辑python脚本并在远程内核上执行它?

Spyder:如何在本地编辑python脚本并在远程内核上执行它?,python,ipython,remote-debugging,spyder,Python,Ipython,Remote Debugging,Spyder,我在Windows7下使用Spyder 2.3.1,在Rasperry-Pi-RASPBIAN Linux操作系统上运行iPython 2.3内核 我可以使用.json文件和本教程连接到外部内核: 但是现在呢?如果我“运行”一个脚本(F5),那么内核将尝试执行该脚本,如下所示: %run "C:\test.py" 错误:找不到文件u'C:\\test.py' 这会返回一个错误ofc,因为脚本放在我的机器上的c:下,而不是放在远程机器/raspberry pi上。我如何告诉Spyder以某种方

我在Windows7下使用Spyder 2.3.1,在Rasperry-Pi-RASPBIAN Linux操作系统上运行iPython 2.3内核

我可以使用.json文件和本教程连接到外部内核:

但是现在呢?如果我“运行”一个脚本(F5),那么内核将尝试执行该脚本,如下所示:

%run "C:\test.py"
错误:找不到文件
u'C:\\test.py'

这会返回一个错误ofc,因为脚本放在我的机器上的c:下,而不是放在远程机器/raspberry pi上。我如何告诉Spyder以某种方式首先将脚本复制到远程机器并在那里执行它

如果我选中“这是一个远程内核”复选框,我将无法再连接到现有内核。那个盒子是什么意思?它会在执行之前通过SSH将脚本复制到远程机器吗?
如果我输入SSH登录信息,我会得到一个“内核似乎意外死亡”错误。

您提到的教程有点过时,因为Spyder现在可以连接到远程内核。 选中“这是一个远程内核”复选框后,将启用对话框中可以输入ssh连接凭据的部分。 (除非您已经手动打开所需的ssh隧道以转发远程内核的进程端口,否则您应该需要此功能…)

此外,ipython连接信息(json文件)必须对应于在raspberry pi上运行的远程内核

最后,当您点击run时,此时无法复制本地pc上的脚本。首选的方法实际上是相反的:使用sshfs之类的工具挂载raspberry pi的文件系统,并在适当的位置编辑它们。计划是在Spyder中实现一个sftp客户机,这样就不需要它,并且您将能够从Spyder的文件资源管理器中探索远程文件系统

总结如下:

1) 假设您已登录raspberry pi,则使用 ipython内核。它应该为您提供要使用的json文件的名称,您应该将其复制到本地pc

2) 在本地pc上的spyder中,使用该json文件和ssh凭据连接到远程内核


我知道这很麻烦,但这是第一步

另一种选择是使用Spyder单元格将文件的全部内容发送到IPython控制台。我认为这比用Samba或sshfs安装远程文件系统更容易(如果不可能或很难做到的话)

通过向文件中添加
#%%
格式的行来定义单元格。例如,假设您的文件是:

# -*- coding: utf-8 -*-

def f(x):
    print(x + x)

f(5)
然后你可以像这样在底部添加一个单元格

# -*- coding: utf-8 -*-

def f(x):
    print(x + x)

f(5)

# %%

通过在单元格上方按Ctrl+Enter,文件的全部内容将立即发送到控制台并进行评估。

site packages\spyderlib
目录中搜索关键字
%run
,我找到了该方法(在
site packages\spyderlib\plugins\ipythonsole.py
)它构造了
%run
命令:

    def run_script_in_current_client(self, filename, wdir, args, debug):
    """Run script in current client, if any"""
    norm = lambda text: remove_backslashes(to_text_string(text))
    client = self.get_current_client()
    if client is not None:
        # Internal kernels, use runfile
        if client.kernel_widget_id is not None:
            line = "%s('%s'" % ('debugfile' if debug else 'runfile',
                                norm(filename))
            if args:
                line += ", args='%s'" % norm(args)
            if wdir:
                line += ", wdir='%s'" % norm(wdir)
            line += ")"
        else: # External kernels, use %run
            line = "%run "
            if debug:
                line += "-d "
            line += "\"%s\"" % to_text_string(filename)
            if args:
                line += " %s" % norm(args)
        self.execute_python_code(line)
        self.visibility_changed(True)
        self.raise_()
    else:
        #XXX: not sure it can really happen
        QMessageBox.warning(self, _('Warning'),
            _("No IPython console is currently available to run <b>%s</b>."
              "<br><br>Please open a new one and try again."
              ) % osp.basename(filename), QMessageBox.Ok)
现在,当我点击F5时,它在远程机器上运行该文件。
我在
Spyder 2.3.9
上,samba共享映射到z:drive。

我想我会在第一篇文章中更新Roy Cai对Spyder 4的回答,以防有人在寻找。罗伊的回答对我来说完美无瑕。Spyder 4已经将相关代码从他编写答案时的位置移走了。该方法现在位于\Lib\site packages\spyder\plugins\ipythonsole中,python文件为plugin.py

否则一切都会像以前一样工作——插入修改过的代码的位置是相同的,相同的更新会修复它


(顺便说一句,保存登录信息以便登录Spyder 4中的远程内核的功能太棒了!)

因此,假设我通过一个已经存在的json文件连接到远程机器上的iPython内核。在没有“这是一个远程内核”复选框的情况下,它已经可以工作了。为什么我需要输入任何SSH凭据?然后蜘蛛会登录到我的raspberry并在那里启动ipython内核并为我获取json文件吗?我使用samba从rasperry pi的主目录加载脚本。然后连接到内核。因此,我可以在本地编辑该文件,然后将选项卡插入ipython控制台并手动“运行xyz.py”(不带F5)。这应该行得通。谢谢如果您使用的是无密码ssh连接,则不需要选中“这是远程内核”框。我想这是你的设置,否则我不明白你是如何连接到你的rasperry pi的。在任何情况下,该功能都可以帮助用户打开ssh隧道,以便他们能够自动连接到其他机器中的内核。但是如果你不需要它,那么你就不需要担心它。酷!,我不知道。我工作。不幸的是,我遇到了一个问题,即您不能使用远程内核STRG+C。在我的应用程序中,我在一些外部LED条纹上运行动画。如果按STRG+C,spyder会告诉您“------------------------------------IPython----------------------内核进程是远程的或未指定的。无法中断----------------------确定-----------------”因此,在使用Raspberry的PWM GPIO引脚写入一些周期后,我会将程序更改为结束循环。是,现在不可能中断外部内核。关于它的一些讨论见此。你能提供更多细节吗?当您点击F5时,您的Windows Spyder似乎会尝试从远程计算机复制代码并在Windows上执行?您不需要打开SSH连接才能将执行命令发送到远程主机吗?我设置spyder,使用op提到的json文件连接到远程ipython内核,当点击f5时,spyder将
%run filepath
发送到ipython内核,op发生错误是因为远程计算机上不存在文件路径,我映射了samba fi
            # ----added to remap local dir to remote dir-------
            localpath = "Z:\wk"
            remotepath = "/mnt/sdb1/wk"
            if localpath in filename:
                # convert path to linux path
                filename = filename.replace(localpath, remotepath)
                filename = filename.replace("\\", "/")
            # ----- END mod