如何从命令行获取持久的python会话?

如何从命令行获取持久的python会话?,python,Python,我想从shell中获得以下行为: $ python --new-session -c '' $ python --use-session -c 'x = 42' $ python --use-session -c 'print x' 42 为什么? 我正在使用许多来自命令行的帮助程序,例如makorender和jinja为我的(C/C++)项目生成文件。每次调用Python时,所有使用的模块都将导入工作区,这需要时间。通过在Python调用中使用持久性工作区,我可以节省大量处理时间 我目前的解

我想从shell中获得以下行为:

$ python --new-session -c ''
$ python --use-session -c 'x = 42'
$ python --use-session -c 'print x'
42
为什么?

我正在使用许多来自命令行的帮助程序,例如
makorender
jinja
为我的(C/C++)项目生成文件。每次调用Python时,所有使用的模块都将导入工作区,这需要时间。通过在Python调用中使用持久性工作区,我可以节省大量处理时间

我目前的解决方案是使用
shelve
在会话之间存储我能存储的所有内容,但这并不方便,我正在寻找一个不太复杂的解决方案


我知道使用Jupyter内核是可能的。不幸的是,在我的系统上,启动连接到现有内核的新Python会话大约需要5到10秒

下面的bash脚本是您所需内容的近似草案:

python会话:
#/usr/bin/env bash
如果[$#-ne 1]]
然后
echo 1>&2“用法:python会话”
出口1
fi
sessionname=“$1”
sessiondir=/tmp/python会话“$sessionname”
stdin=“$sessiondir/stdin”
stdout=“$sessiondir/stdout”
(完)
{
echo正在退出python会话“$sessionname”
rm-rf“$sessiondir”
}
新闻会话()
(
回显“启动新会话$sessionname”
mkdir“$sessiondir”
陷阱“结束会话”退出
触摸“$stdin”
触摸“$stdout”
tail-f“$stdin”| python-i-c“import sys;sys.ps1=sys.ps2=''”>“$stdout”
)
如果[!-d“$sessiondir”]
然后
新闻会话与否认
而[!-e“$stdout”];睡眠0.01;完成
fi
echo“已连接到python会话$1(通过键入CTRL-D离开会话)”
尾部-f-n 0“$stdout”&
tailpid=$!
陷阱“杀死$tailpid”退出
cat>>“$stdin”
演示:
$。/python会话1
开始新的会话1
已连接到python会话1(通过键入CTRL-D离开会话)
x=123
美元/python会话1
已连接到python会话1(通过键入CTRL-D离开会话)
打印x
123
美元/python会话2
开始新的会话2
已连接到python会话2(通过键入CTRL-D离开会话)
打印x
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
名称错误:未定义名称“x”
x='abc'
美元/python会话1
已连接到python会话1(通过键入CTRL-D离开会话)
打印x
123
美元/python会话2
已连接到python会话2(通过键入CTRL-D离开会话)
打印x
abc
退出()
退出python会话2
美元/python会话1
已连接到python会话1(通过键入CTRL-D离开会话)
退出()
退出python会话1
$
执行草案的局限性
  • 必须通过输入
    exit()
    命令,然后再输入一行(甚至是空的)命令来停止会话。在此之后,您仍然必须按CTRL-D才能断开与现在不存在的会话的连接

  • 未捕获python会话的标准错误流

#!/usr/bin/env bash

if [[ $# -ne 1 ]]
then
    echo 1>&2 "Usage: python-session <session-name>"
    exit 1
fi

sessionname="$1"
sessiondir=/tmp/python-session."$sessionname"
stdin="$sessiondir/stdin"
stdout="$sessiondir/stdout"

endsession()
{
    echo Exiting python session "$sessionname"
    rm -rf "$sessiondir"
}

newsession()
(
    echo "Starting new session $sessionname"
    mkdir "$sessiondir"
    trap "endsession" EXIT
    touch "$stdin"
    touch "$stdout"
    tail -f "$stdin"|python -i -c "import sys; sys.ps1=sys.ps2=''">"$stdout"
)

if [ ! -d "$sessiondir" ]
then
    newsession & disown
    while [ ! -e "$stdout" ]; do sleep 0.01; done
fi

echo "Connected to python session $1 (leave the session by typing CTRL-D)"
tail -f -n 0 "$stdout"&
tailpid=$!
trap "kill $tailpid" EXIT
cat >> "$stdin"
$ ./python-session 1
Starting new session 1
Connected to python session 1 (leave the session by typing CTRL-D)
x=123
$ ./python-session 1
Connected to python session 1 (leave the session by typing CTRL-D)
print x
123
$ ./python-session 2
Starting new session 2
Connected to python session 2 (leave the session by typing CTRL-D)
print x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
x='abc'
$ ./python-session 1
Connected to python session 1 (leave the session by typing CTRL-D)
print x
123
$ ./python-session 2
Connected to python session 2 (leave the session by typing CTRL-D)
print x
abc
exit()

Exiting python session 2
$ ./python-session 1
Connected to python session 1 (leave the session by typing CTRL-D)
exit()

Exiting python session 1
$