据我所见,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"],
},
}
这里的重要注释是target 和cancel,它们将构建与插件提供的命令联系起来,working_dir 确保当前目录是当前文件所在的目录(因为这就是 input 和 output 文件的预期位置),并且 \\$temp_file 用于引用包含结果代码的临时输出文件。
作为对此的说明,如果发生错误,错误中的行号将略微偏离,因为它们引用顶部有额外内容的文件,如果您导航到它,您将打开临时文件,这不是您应该编辑的。
所以,总而言之,sn-p 可能是最安全、最快的方式。