首页 > 解决方案 > 将用户输入插入后端 python shell

问题描述

我正在做一个宠物项目,我正在尝试制作 Jupyter 的命令行版本(我完全理解这听起来多么愚蠢,“为什么不只使用 Python shell”,这只是为了好玩)。我一直在想办法在后台启动一个 Python 实例,允许我将用户的输入插入到那个 shell 中。但我只是找不到任何方法。有什么合理的方法可以做到这一点吗?

谢谢!

编辑:我正在考虑类似Jython的东西,但如果可能的话,我更愿意完全在 Python 中完成这项工作。

标签: pythonshelljupyter-notebook

解决方案


我可以想到两种方法来做到这一点。第一种方法是使用exec执行用户输入代码。

while True:
    user_input = input("Python command to execute: ")

    try:
        exec(user_input)
    except Exception as e:
        print("Error thrown.")

然而,这也有其局限性。您必须编写一些自定义代码来捕获错误、适当地抛出错误等。第二种方法涉及更多,但也更通用。您使用Everything is a file方法,并将用户输入(无论是通过 shell、网站还是其他任何方式)视为文件。然后,使用该文件执行它。您可以在执行前始终检查文件是否已更新,让 shell 始终处于打开状态:

import hashlib
import runpy
import time

FILE = "./file.py"

def get_file_md5(file_name):
    with open(file_name, "rb") as f:
        return hashlib.md5(f.read()).hexdigest()

md5 = get_file_md5(FILE)
first_run = True

while True:
    current_md5 = get_file_md5(FILE)
    if md5 != current_md5 or first_run:
        first_run = False
        md5 = current_md5

        try:
            runpy.run_path(FILE)
        except Exception as e:
            print("Error", e)
    else:
        time.sleep(1)

您可能会发现我对另一个(模糊相关的)问题给出的答案很有趣且有用


关于下文。通知exec(object[, globals[, locals]])文件:

在所有情况下,如果省略了可选部分,则代码将在当前范围内执行。如果只提供全局变量,则它必须是字典(而不是字典的子类),它将用于全局变量和局部变量。

所以你可以这样做:

exec_globals = {}
exec('a = 10; print(a)', exec_globals)

print("\na in exec_globals: ", 'a' in exec_globals)
print("exec_globals['a'] =", exec_globals['a'])

print("\na in globals(): ", 'a' in globals())
print(a)

以上将输出:

10

a in exec_globals:  True
exec_globals['a'] = 10

a in globals():  False

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    print(a)
NameError: name 'a' is not defined

推荐阅读