我发现自己经常使用 Python 的解释器来处理数据库、文件等——基本上是对半结构化数据进行大量手动格式化。我没有像我想的那样经常正确地保存和清理有用的位。有没有办法将我的输入保存到 shell 中(db 连接、变量分配、少量 for 循环和一些逻辑)——交互式会话的一些历史记录?如果我使用类似的东西,script
我会得到太多的标准输出噪音。我真的不需要腌制所有的对象——尽管如果有一个解决方案可以做到这一点,那就没问题了。理想情况下,我只剩下一个脚本,该脚本作为我以交互方式创建的脚本运行,我可以删除我不需要的位。有没有这样的包,或者DIY方法?
20 回答
如果您喜欢使用交互式会话, IPython非常有用。例如,对于您的用例,有一个%save
魔术命令,您只需输入%save my_useful_session 10-20 23
以将输入的第 10 行到第 20 行和第 23 行保存到my_useful_session.py
(为了帮助解决这个问题,每一行都以它的编号为前缀)。
此外,文档指出:
此函数对输入范围使用与%history相同的语法,然后将行保存到您指定的文件名。
例如,这允许引用较旧的会话,例如
%save current_session ~0/
%save previous_session ~1/
查看演示页面上的视频以快速了解这些功能。
来自 Andrew Jones 的网站(存档):
import readline
readline.write_history_file('/home/ahj/history')
有办法做到这一点。将文件存储在~/.pystartup
...
# Add auto-completion and a stored history file of commands to your Python
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
# to it: "export PYTHONSTARTUP=/home/user/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
# full path to your home directory.
import atexit
import os
import readline
import rlcompleter
historyPath = os.path.expanduser("~/.pyhistory")
def save_history(historyPath=historyPath):
import readline
readline.write_history_file(historyPath)
if os.path.exists(historyPath):
readline.read_history_file(historyPath)
atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath
然后PYTHONSTARTUP
在你的 shell 中设置环境变量(例如 in ~/.bashrc
):
export PYTHONSTARTUP=$HOME/.pystartup
您还可以添加它以免费获得自动完成功能:
readline.parse_and_bind('tab: complete')
请注意,这只适用于 *nix 系统。因为 readline 仅在 Unix 平台上可用。
如果您使用的是IPython ,您可以使用带有-f参数 pe的魔术函数%history将您之前的所有命令保存到一个文件中:
%history -f /tmp/history.py
安装Ipython并通过运行以下命令打开 Ipython 会话后:
ipython
从您的命令行,只需运行以下 Ipython 'magic' 命令即可自动记录整个 Ipython 会话:
%logstart
这将创建一个唯一命名的 .py 文件并存储您的会话,以供以后用作交互式 Ipython 会话或在您选择的脚本中使用。
此外,reinteract为您提供了一个类似于笔记本的 Python 会话界面。
除了 IPython,类似的实用程序bpython具有“将您输入的代码保存到文件”功能
我不得不努力寻找答案,我对 iPython 环境非常陌生。
这将起作用
如果您的 iPython 会话看起来像这样
In [1] : import numpy as np
....
In [135]: counter=collections.Counter(mapusercluster[3])
In [136]: counter
Out[136]: Counter({2: 700, 0: 351, 1: 233})
你想保存从 1 到 135 的行,然后在同一个 ipython 会话中使用这个命令
In [137]: %save test.py 1-135
这会将所有 python 语句保存在当前目录(您启动 ipython 的位置)中的 test.py 文件中。
有 %history 魔法打印和保存输入历史(以及可选的输出)。
要将当前会话存储到名为的文件中my_history.py
:
>>> %hist -f my_history.py
历史 IPython 存储您输入的命令和它产生的结果。您可以使用向上和向下箭头键轻松浏览以前的命令,或者以更复杂的方式访问您的历史记录。
您可以使用 %history 魔术函数来检查过去的输入和输出。以前会话的输入历史保存在数据库中,IPython 可以配置为保存输出历史。
其他几个魔术函数可以使用您的输入历史记录,包括 %edit、%rerun、%recall、%macro、%save 和 %pastebin。您可以使用标准格式来引用行:
%pastebin 3 18-20 ~1/1-5
这将占用当前会话的第 3 行和第 18 到 20 行,以及前一会话的第 1-5 行。
查看 % 历史记录?对于 Docstring 和更多示例。
此外,一定要探索%store 魔术的功能,以便在 IPython 中实现变量的轻量级持久性。
在 IPython 的数据库中存储变量、别名和宏。
d = {'a': 1, 'b': 2}
%store d # stores the variable
del d
%store -r d # Refresh the variable from IPython's database.
>>> d
{'a': 1, 'b': 2}
要在启动时自动恢复存储的变量,c.StoreMagic.autorestore = True
请在 ipython_config.py 中指定。
就 Linux 而言,可以使用script
命令来记录整个会话。它是util-linux
软件包的一部分,因此应该在大多数 Linux 系统上。您可以创建将调用script -c python
并将保存到typescript
文件中的别名或函数。例如,这里是一个此类文件的重印本。
$ cat typescript
Script started on Sat 14 May 2016 08:30:08 AM MDT
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'Hello Pythonic World'
Hello Pythonic World
>>>
Script done on Sat 14 May 2016 08:30:42 AM MDT
这里的小缺点是script
记录所有内容,甚至换行,每当你点击退格等。所以你可能想用它col
来清理输出(见这篇关于 Unix&Linux Stackexchange 的帖子)。
还有另一种选择——pyslice。在“wxpython 2.8 docs demos and tools”中,有一个名为“pyslices”的开源程序。
你可以像编辑器一样使用它,它也支持像控制台一样使用——像交互式解释器一样执行每一行,并立即回显。
当然,所有的代码块和每个块的结果都会自动记录到一个txt文件中。
结果记录在相应的代码块后面。很方便。
如果您使用bpython,您的所有命令历史记录默认保存到~/.pythonhist
.
要保存命令以供以后重用,您可以将它们复制到 python 脚本文件:
$ cp ~/.pythonhist mycommands.py
然后编辑该文件以清理它并将其放在 Python 路径下(全局或虚拟环境的站点包、当前目录、在 *.pth 中提及或其他方式)。
要将命令包含到您的 shell 中,只需从保存的文件中导入它们:
>>> from mycommands import *
在IPython中,我首先使用
In [2]: %hist
查看我过去的代码。我选择要保存的块,然后my_file.py
使用%%file
魔法(缩写%%writefile
)将其粘贴到文件中
In [3]: %%file my_file.py
...: # paste code here
...:
...:
最后击中返回两次。
要附加到文件,请使用选项-a
: %%file -a my_file.py
。
如果需要,我可以使用感叹号在底层命令行中列出、编辑等文件
In [5]: !ls -l my_file.py
In [6]: !vi my_file.py
一些评论询问如何一次保存所有 IPython 输入。对于 IPython 中的 %save 魔法,您可以如下所示以编程方式保存所有命令,以避免出现提示消息并避免指定输入数字。currentLine = len(In)-1 %save -f my_session 1-$currentLine
该-f
选项用于强制文件替换,并len(IN)-1
在 IPython 中显示当前输入提示,允许您以编程方式保存整个会话。
对于那些使用spacemacs
, 以及ipython
附带的python-layer
, save magic 会产生很多不需要的输出,因为在后台工作的恒定自动完成命令,例如:
len(all_suffixes)
';'.join(__PYTHON_EL_get_completions('''len'''))
';'.join(__PYTHON_EL_get_completions('''all_substa'''))
len(all_substantives_w_suffixes)
';'.join(__PYTHON_EL_get_completions('''len'''))
';'.join(__PYTHON_EL_get_completions('''all'''))
';'.join(__PYTHON_EL_get_completions('''all_'''))
';'.join(__PYTHON_EL_get_completions('''all_w'''))
';'.join(__PYTHON_EL_get_completions('''all_wo'''))
';'.join(__PYTHON_EL_get_completions('''all_wor'''))
';'.join(__PYTHON_EL_get_completions('''all_word'''))
';'.join(__PYTHON_EL_get_completions('''all_words'''))
len(all_words_w_logograms)
len(all_verbs)
为避免这种情况,只需像通常保存任何其他缓冲区一样保存 ipython 缓冲区:spc f s
我想建议另一种通过 linux 上的 tmux 维护 python 会话的方法。您运行 tmux,将您自己附加到您打开的会话(如果直接打开后未附加)。执行 python 并做任何你正在做的事情。然后从会话中分离。从 tmux 会话中分离不会关闭会话。会议保持开放。
这种方法的优点: 您可以从任何其他设备附加到此会话(如果您可以 ssh 您的电脑)
此方法的缺点: 此方法不会放弃打开的 python 会话使用的资源,直到您实际存在 python 解释器。
在 XUbuntu 上保存输入和输出:
- 在 XWindows 中,从 Xfce 终端应用程序运行 iPython
- 单击
Terminal
顶部菜单栏并save contents
在下拉菜单中查找
我发现这可以保存输入和输出,一直到我打开终端时。这不是 ipython 特定的,并且可以与 ssh 会话或从终端窗口运行的其他任务一起使用。
您可以使用内置函数 open:我在需要存储一些历史记录(包括计算器等)的所有程序中都使用它,例如:
#gk-test.py or anything else would do
try: # use the try loop only if you haven't created the history file outside program
username = open("history.txt").readline().strip("\n")
user_age = open("history.txt").readlines()[1].strip("\n")
except FileNotFoundError:
username = input("Enter Username: ")
user_age = input("Enter User's Age: ")
open("history.txt", "w").write(f"{username}\n{user_age}")
#Rest of the code is secret! try it your own!
我要感谢所有喜欢我评论的人!谢谢您阅读此篇!