【问题标题】:Run a python snippet with every run on sublime text每次在 sublime 文本上运行时运行一个 python 片段
【发布时间】:2021-06-22 12:05:56
【问题描述】:

我在运行的每个代码中都使用了以下 sn-p。

import sys
sys.stdin, sys.stdout = open('input', 'r'), open('output', 'w')

有什么办法可以让我运行的每一个.py 都运行这两行。

在 Sublime Text 上,这是我用来将输出重定向到文件的构建配置,但它不起作用。

{
    "cmd": ["/home/jithin/venv/bin/python", "-u", "$file" ,">","/home/jithin/temp/hackerrank/output"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}
    

是否有像 --stdout 这样的标志来将代码的输出重定向到文件。

注意。我不能在代码中使用包含任何行,因为我正在练习竞争性编程,所以我通常将代码从问题复制并粘贴到 ST。 如果有不同的方法,我不需要每次都包含上面的 sn-p。 同样对于粘贴回来,我可以简单地使用 Ctrl + A 和 Ctrl + V。

【问题讨论】:

  • 否,因为我需要在代码中添加import os filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): execfile(filename)。我正在寻找一种通过不包含任何代码行来解决问题的方法,以便我可以轻松复制和粘贴。
  • 可以在构建配置中做任何事情吗??
  • 如果你打算使用cmd而不是shell_cmd,你需要在你的构建系统中添加"shell": true,来告诉Sublime它应该让shell运行命令;否则您将 shell 命令(即重定向)作为参数提供给 Python,它可能不会像您期望的那样处理
  • 我试过了,但没有正确执行,可能是synatx中的错误,您可以发布构建配置吗?

标签: python sublimetext3


【解决方案1】:

据我所见,Python 没有内置方法允许您执行任意脚本命令以及完整的脚本,因此可用的选项归结为手动将样板文件放入每个文件或动态添加它当你运行代码时。

一般来说,我的建议是创建一个为您插入此代码的 sn-p,这样您就不必手动复制和粘贴它。为此,您可以选择 Tools > Developer > New Snippet... 并将存根替换为以下内容,然后将文件另存为 sublime-snippet 文件在 Sublime 建议的位置:

<snippet>
    <content><![CDATA[
import sys
sys.stdin, sys.stdout = open('input', 'r'), open('output', 'w')

]]></content>
    <tabTrigger>stub</tabTrigger>
    <description>Insert IO redirect stubs for competetive coding</description>
    <scope>source.python</scope>
</snippet>

根据需要更改选项卡触发器,但现在在新的 Python 文件中 stubTab 将为您插入代码。

如果您愿意,也可以构建一个自动将存根添加到每个执行的 Python 文件开头的构建(但 sn-p 更容易)。

为此,有这个插件(如果您不确定如何使用,请参阅this video on installing plugins)。


import sublime
import sublime_plugin

import os
import tempfile

from Default.exec import ExecCommand


_stub = """
import sys
sys.stdin, sys.stdout = open('input', 'r'), open('output', 'w')

"""


class PythonWithRedirectExecCommand(ExecCommand):
    def run(self, **kwargs):
        view = self.window.active_view()
        if view.file_name() is None or not os.path.exists(view.file_name()):
            return self.window.status_message("Cannot build; no file associated with the current view")

        self.tmp_file = self.get_temp_file(view)

        variables = {"temp_file": self.tmp_file}
        kwargs = sublime.expand_variables(kwargs, variables)

        super().run(**kwargs)

    def get_temp_file(self, view):
        handle, name = tempfile.mkstemp(text=True, suffix=".py")
        with os.fdopen(handle, mode="wt", encoding="utf-8") as handle:
            handle.write(_stub)
            with open(view.file_name()) as source:
                handle.write(source.read())

        return name

    # NOTE: If you are using Sublime Text 3, change this line and the
    #       next use to use finished instead of on_finished.
    def on_finished(self, proc):
        super().on_finished(proc)

        # If the current build didn't finish or it was manually killed, leave.
        if proc != self.proc or proc.killed:
            return

        try:
            # If the build succeeded, delete the temporary file; we will
            # leave it alone if the build fails so that it's possible to
            # navigate to it.
            exit_code = proc.exit_code()
            if exit_code == 0 or exit_code is None:
                os.remove(self.tmp_file)
        finally:
            self.tmp_file = None

这实现了一个替换构建目标,当执行该目标时,将创建一个包含存根内容以及当前文件内容的临时文件。

重要提示:这是在 Sublime Text ~~4~~ 中开发的;它也可以在 Sublime Text 3 中使用,但如果您使用 ST3,则需要将对 on_finished 的两个引用更改为 finished;否则插件不会清理临时文件。可能还值得注意的是,由于下面列出的原因,如果运行失败,临时文件不会被删除。

要使用它,您需要一个与此类似的构建系统(根据需要修改命令;这是一个通用构建):

{
    "target": "python_with_redirect_exec",
    "cancel": {"kill": true},

    "cmd": ["python3", "-u", "\\$temp_file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",

    "working_dir": "${file_path}",

    "env": {"PYTHONIOENCODING": "utf-8"},

    "windows": {
        "cmd": ["py", "-u", "\\$temp_file"],
    },
}

这里的重要注释是targetcancel,它们将构建与插件提供的命令联系起来,working_dir 确保当前目录是当前文件所在的目录(因为这就是 inputoutput 文件的预期位置),并且 \\$temp_file 用于引用包含结果代码的临时输出文件。

作为对此的说明,如果发生错误,错误中的行号将略微偏离,因为它们引用顶部有额外内容的文件,如果您导航到它,您将打开临时文件,这不是您应该编辑的。

所以,总而言之,sn-p 可能是最安全、最快的方式。

【讨论】:

  • 谢谢。我现在按照第一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 2016-07-24
  • 2019-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-10
相关资源
最近更新 更多