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

Python-在命令行应用程序中传递参数,python,parameters,python-2.7,Python,Parameters,Python 2.7,我需要编写一个命令行应用程序,比如shell。所以它将包括命令等。问题是我不知道如何将参数传递给模块中的函数。例如: 用户写入:function1 folder1 程序现在应该将'folder1'参数传递给function1函数,并运行它。但它还必须支持具有不同参数的其他功能,例如: 用户输入:function2folder2--exampleparam 如何让它工作?我的意思是,我可以编写一个模块,用python导入它,然后只使用python控制台,但事实并非如此。我需要一个脚本,接受命令输入

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

用户写入:function1 folder1 程序现在应该将'folder1'参数传递给function1函数,并运行它。但它还必须支持具有不同参数的其他功能,例如:

用户输入:function2folder2--exampleparam

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

我尝试使用eval(),但这并不能解决params的问题。或者可能有,但我看不到?

看看。这有助于向python脚本传递和接收shell样式参数

更新: 显然,
optparse
现在已经被弃用,并且是解析命令行参数的首选选项

看一看。这有助于向python脚本传递和接收shell样式参数

更新: 显然,
optparse
现在已经被弃用,并且是解析命令行参数的首选选项

怎么样?有关更高级的内容,请查看
optpass
现在似乎贬值了,但关于这个问题这里有一个问题。

怎么样?有关更高级的内容,请查看
optpass
现在似乎贬值了,但关于这个问题这里有一个问题

import sys

def main(arg):
    return arg

print main(sys.argv[1])
其中sys.argv[0]是正在运行的.py文件,它后面的所有文件都是每个参数。您可以检查列表的长度,然后遍历它,根据需要解析它们,并将正确的内容传递给每个函数


其中sys.argv[0]是正在运行的.py文件,它后面的所有文件都是每个参数。您可以检查列表的长度,然后对其进行迭代,并根据需要对其进行解析,然后将正确的内容传递给每个函数。这正是您需要的:

http://docs.python.org/2/library/optparse.html
或者,您可以编写自己的自定义opt解析器(尽管是最低限度的)

<> P>但是,如果脚本需要在Python 3及以后运行,则需要考虑Myto.\/P>
希望有帮助。

看看python中的optparse模块。这正是您需要的:

http://docs.python.org/2/library/optparse.html
或者,您可以编写自己的自定义opt解析器(尽管是最低限度的)

<> P>但是,如果脚本需要在Python 3及以后运行,则需要考虑Myto.\/P>
希望这会有所帮助。

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

第二部分——将函数的字符串名称转换为函数调用——可以使用或调度dict完成,该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)


当命令被输入到命令行本身时,上述方法就起作用了。如果命令被输入到
stdin
,那么我们需要做一些不同的事情

一种简单的方法是调用
raw\u 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
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))
main.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
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))

另一种更复杂的处理方法是使用@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()
有关如何使用cmd模块的更多信息,请参阅


运行上述代码会产生如下结果:

% 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

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

第二部分——将函数的字符串名称转换为函数调用——可以使用或调度dict完成,该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)


当命令被输入到命令行本身时,上述方法就起作用了。如果命令被输入到
stdin
,那么我们需要做一些不同的事情

一种简单的方法是调用
raw\u 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
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))
main.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
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))

另一种更复杂的处理方法是使用@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()
有关如何使用cmd模块的更多信息,请参阅


运行上述代码会产生如下结果:

% 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

optparse
是不推荐使用的,因为python 2.7和argparse更灵活。 unutbu的方法是安全的,但如果您提供白名单,我建议您让用户知道哪些功能可以接受

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

parser = argparse.ArgumentParser()
parser.add_argument('function', choices=dispatch.keys() )

仅供参考:如果解析不是太复杂,看起来是一个非常好的包,因为Python2.7和argparse更灵活,所以optparse被弃用。 unutbu的方法是安全的,但如果您提供白名单,我建议您让用户知道哪些功能可以接受

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

parser = argparse.ArgumentParser()
parser.add_argument('function', choices=dispatch.keys() )

仅供参考:如果解析不是太复杂,第二部分看起来像是一个非常好的包,那么也可以看看
cmd
模块。这对我来说很有效,但我仍然不知道如何从另一个脚本实际启动命令。如果我将其放入模块中的函数中,并像这样调用它:module.function,则不会发生任何事情。但是,如果我这样做:module.function 1,我会得到一个语法错误。用参数modu调用它没有意义