设计像交互式shell一样的python
Design python like interactive shell
像
interactive shell
一样的python背后的设计模式是什么?我想为我的服务器执行此操作,但我最终会得到很多if - then- else
模式。
例如,当我开始python interpreter
时,我得到这样的东西
Python 2.6.7 (r267:88850, Feb 2 2012, 23:50:20)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> help
帮助后,提示更改为帮助
Welcome to Python 2.6! This is the online help utility.
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".
help>
我认为这是read-eval loop
设计之王。
对于 REPL,您需要一个上下文(存储 REPL 状态的对象)、一个命令解析器(解析输入并生成 AST)以及一种将命令映射到操作的方法(操作通常只是修改上下文和/或产生副作用的函数)。
一个简单的 REPL 可以像下面这样实现,其中上下文是使用简单的字典实现的,AST 只是在空格上拆分的输入命令,字典用于将命令映射到操作:
context = {}
commands = {}
def register(func):
""" convenience function to put `func` into commands map """
# in C++, you cannot introspect the function's name so you would
# need to map the function name to function pointers manually
commands[func.__name__] = func
def parse(s):
""" given a command string `s` produce an AST """
# the simplest parser is just splitting the input string,
# but you can also produce use a more complicated grammer
# to produce a more complicated syntax tree
return s.split()
def do(cmd, commands, context):
""" evaluate the AST, producing an output and/or side effect """
# here, we simply use the first item in the list to choose which function to call
# in more complicated ASTs, the type of the root node can be used to pick actions
return commands[cmd[0]](context, cmd)
@register
def assign(ctx, args):
ctx[args[1]] = args[2]
return '%s = %s' % (args[1], args[2])
@register
def printvar(ctx, args):
print ctx[args[1]]
return None
@register
def defun(ctx, args):
body = ' '.join(args[2:])
ctx[args[1]] = compile(body, '', 'exec')
return 'def %s(): %s' % (args[1], body)
@register
def call(ctx, args):
exec ctx[args[1]] in ctx
return None
# more commands here
context['PS1'] = "> "
while True:
# READ
inp = raw_input(context["PS1"])
# EVAL
cmd = parse(inp)
out = do(cmd, commands, context)
# PRINT
if out is not None: print out
# LOOP
示例会话:
> assign d hello
d = hello
> printvar d
hello
> assign PS1 $
PS1 = $
$defun fun print d + 'world'
def fun(): print d + 'world'
$call fun
helloworld
通过更多的技巧,您甚至可以将上下文和命令字典合并在一起,从而允许在 shell 的语言中修改 shell 的命令集。
这个设计模式的名称,如果它有一个名字,是Read-Eval-Print Loop设计模式;所以是的,你的问题有点回答自己。
相关文章:
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- 我如何在C++像在 Python 中一样实现 f 字符串?
- Python 等效代码,可像C++一样直接附加两个整数
- 像在 Python 中一样C++循环中的参数解析。为什么不起作用?
- C++中是否有一个功能可以创建一个像Python的"numpy.bmat"一样简单的块矩阵?
- C++如何像python一样插入
- 如何在cv::dft中指定FFT长度,就像在Python numpy.FFT.rfft中一样
- 设计像交互式shell一样的python
- 如何制作更具表现力的 Python 迭代器?就像 C++ 迭代器一样
- 如何使c++像python一样给出详细的异常信息
- 定义一个像 Python "with" 语句一样工作的 C 宏有什么缺点?
- c++中的循环和python中的一样(基于范围的for)
- c++中是否有任何数据结构或库可以像Python列表和字典一样工作?
- 如何在Python中像指针一样高效地迭代数组