【问题标题】:Create a sort of command line for a python server为 python 服务器创建一种命令行
【发布时间】:2015-10-19 22:23:33
【问题描述】:

我一直在试验 Python 套接字服务器等。我遇到了一个想法,但我很难实现它。我希望服务器端能够输入不同的命令,用于启动和停止服务器,以及执行各种其他任务。我的问题是,当我开始有很多命令时,我的程序最终看起来像意大利面条:

if command == "start":
    print("Starting server")
    time.sleep(1)
    listener_thread.start()
elif command == "stop":
    print("Stopping server...")
    time.sleep(1)
    listener_thread.stop()
elif command in ["q", "quit"]:
    print("Quitting server...")
    time.sleep(1)
    for t in connections:
        t.stop()
    listener_thread.stop()
    exit()
else:
    print("Invalid command")

我的一个已经编程一段时间的朋友说我应该尝试使用字典来存储每个命令的函数引用。我创建了一个这样的字典:

commands = {
    "start": cmd_start, # This would be a reference to cmd_start()
    "stop": cmd_stop, # Same here and so forth
    "quit": cmd_quit
}

我会这样称呼这些命令:

while True:
    command = input("enter a command: ")
    if command in commands:
        commands[command]()

这种方法的问题是有时我想要一个带有多个参数的命令,有时我不需要。我希望能够使用具有不同参数的不同命令,指定它们所需的参数,并检查以确保该命令是具有所有必需参数的有效命令。我是编程新手,我尝试过想一种干净的方法来实现它。我在谷歌上没有发现任何有用的东西,所以希望有人可以帮助我。谢谢。

【问题讨论】:

  • 我认为您对命令映射的想法很好,您要做的就是使每个命令的参数成为参数的变量列表并解析用户的输入。然后调用该命令并将用户输入的所有额外参数传递给它。
  • 尝试了解 *args 和 **kwargs 参数。
  • 在您的字典中查找输入的第一个单词。然后按照上述 2 建议使用 args、kwargs 并将 words[1:] 传递给命令并让它弄清楚要做什么。我会在 argparse 模块中起草带有参数的命令。
  • 查找click 库或argparse 模块。
  • 这是我想出的:pastebin.com/Kqc5gky4

标签: python command


【解决方案1】:

如果您知道命令的结构,这是一项解析任务,它取决于格式。除此之外,您可以发送可变长度参数using the star operator *(您也可以使用** 发送关键字参数,但我会从这个开始)。

这是一个简单的例子:

command = input("enter a command: ")
arguments = input("enter arguments separated by a single space: ").split()
if command in commands:
    commands[command](*arguments)

请注意,这会将所有参数作为字符串发送。这是一个基本的演示:

>>> def func_with_three_params(a, b, c):
...     print a, b, c
... 
>>> three_args = "1 2 3".split()
>>> func_with_three_params(*three_args)
1 2 3

正如您问题的 cmets 中所述,这是一项非常常见的任务,并且确实存在解析各种常见格式的库。一个常用的(我也用)是argparse

【讨论】:

  • 我的印象是 argparse 用于在运行时传递命令,而不是在脚本运行时传递。无论如何,我尝试了你和其他人所说的关于阅读 *args 和 **kwargs 的内容。这是我想出的:pastebin.com/Kqc5gky4 - 它看起来足够像 Python 吗?有什么建议吗?
  • 这是常见的用途,是的 - 但可能有一种方法可以动态地将参数挂钩。可能使用parse_args。关于您的代码 - 试试代码审查网站。
【解决方案2】:

一个接近海报原始源代码的简单工作示例:

tokens = input("$ ").split()

command, arguments = tokens[0], tokens[1:]

def start_handler(start_line, end_line):
    print("Starting from {} to {}".format(start_line, end_line))

commands = {
  "start": start_handler    
}

commands[command](*arguments)

您可以输入如下命令:start 1 20,它会将 1 和 20 传递给启动处理程序。示例输出:

$  start 1 20
Starting from 1 to 20

【讨论】:

  • 我喜欢你使用元组分割参数和命令的方式。它使代码更具可读性。我肯定会用它来调整我的程序。
猜你喜欢
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2017-08-16
  • 2018-08-19
  • 1970-01-01
相关资源
最近更新 更多