Python - 在命令行应用程序中传递参数

Mar*_*zek 0 python parameters python-2.7

我需要编写一个命令行应用程序,就像一个shell.所以它将包括命令等.事情是我不知道如何将参数传递给模块中的函数.例如:

用户写道:function1 folder1程序现在应该将'folder1'参数传递给function1函数,然后运行它.但它也必须支持具有不同参数的其他函数ex:

用户输入:function2 folder2 --exampleparam

如何使这个工作?我的意思是,我可以编写一个模块,在python中导入它并只使用python控制台,但事实并非如此.我需要一个接受命令输入并运行它的脚本.

我试图使用eval(),但这并没有解决params的问题.或许它确实如此,但我没有看到它?

unu*_*tbu 6

问题的第一部分 - 解析命令行 - 可以用argparse解决.

第二部分 - 将函数的字符串名称转换为函数调用 - 可以使用exec或从字符串映射到函数对象的调度dict 来完成.

我建议不要使用exec此功能,因为允许用户从命令行调用任意Python函数可能会很危险.相反,制作允许功能的白名单:

import argparse


def foo(path):
    print('Running foo(%r)' % (path, ))


def bar(path):
    print('Running bar(%r)' % (path, ))

dispatch = {
    'foo': foo,
    'bar': bar,
}

parser = argparse.ArgumentParser()
parser.add_argument('function')
parser.add_argument('arguments', nargs='*')
args = parser.parse_args()

dispatch[args.function](*args.arguments)
Run Code Online (Sandbox Code Playgroud)
% test.py foo 1
Running foo('1')
% test.py bar 2
Running bar('2')
% test.py baz 3
KeyError: 'baz'
Run Code Online (Sandbox Code Playgroud)

当命令键入命令行本身时,上述方法有效.如果输入命令stdin,那么我们需要做一些不同的事情.

一种简单的方法是调用raw_input从中获取字符串stdin.然后我们可以用argparse解析字符串,如上所述:

shmod.py:

import argparse


def foo(path):
    print('Running foo(%r)' % (path, ))


def bar(path):
    print('Running bar(%r)' % (path, ))

dispatch = {
    'foo': foo,
    'bar': bar,
}

def parse_args(cmd):
    parser = argparse.ArgumentParser()
    parser.add_argument('function')
    parser.add_argument('arguments', nargs='*')
    args = parser.parse_args(cmd.split())
    return args
Run Code Online (Sandbox Code Playgroud)

main.py:

import shmod

while True:
    cmd = raw_input('> ')
    args = shmod.parse_args(cmd)
    try:
        shmod.dispatch[args.function](*args.arguments)
    except KeyError:
        print('Invalid input: {!r}'.format(cmd))
Run Code Online (Sandbox Code Playgroud)

处理此问题的另一种更复杂的方法是使用cmd模块,如注释中提到的@chepner.

from cmd import Cmd


class MyInterpreter(Cmd):

    prompt = '> '

    def do_prompt(self, line):
        "Change the interactive prompt"
        self.prompt = line + ': '

    def do_EOF(self, line):
        return True

    def do_foo(self, line):
        print('Running foo {l}'.format(l=line))

    def do_bar(self, line):
        print('Running bar {l}'.format(l=line))

if __name__ == '__main__':
    MyInterpreter().cmdloop()
Run Code Online (Sandbox Code Playgroud)

有关如何使用cmd模块的更多信息,请参阅Doug Hellman的优秀教程.


运行上面的代码产生如下结果:

% test.py
> foo 1
Running foo 1
> foo 1 2 3
Running foo 1 2 3
> bar 2
Running bar 2
> baz 3
*** Unknown syntax: baz 3
Run Code Online (Sandbox Code Playgroud)