1

シェルのようなコマンド ライン アプリケーションを作成する必要があります。したがって、コマンドなどが含まれます。問題は、モジュール内の関数にパラメーターを渡す方法がわからないことです。例えば:

ユーザーの書き込み: function1 folder1 プログラムは、'folder1' パラメーターを function1 関数に渡して実行する必要があります。ただし、さまざまなパラメーターを持つ他の関数もサポートする必要があります。例:

ユーザー入力: function2 folder2 --exampleparam

これを機能させるにはどうすればよいですか?つまり、モジュールを作成して Python にインポートし、Python コンソールを使用するだけでよいのですが、そうではありません。コマンド入力を受け取って実行するスクリプトが必要です。

eval() を使用しようとしましたが、params の問題は解決しません。それとも、そうかもしれませんが、私はそれを見ませんか?

4

6 に答える 6

7

問題の最初の部分 (コマンド ラインの解析) はargparseで解決できます。

2 番目の部分 (関数の文字列名を関数呼び出しに変換する) は、文字列から関数オブジェクトにマップするexecまたはディスパッチ dict を使用して実行できます。

ユーザーがコマンドラインから任意の Python 関数を呼び出せるようにすることは危険な場合があるため、これには使用しないことをお勧めします。exec代わりに、許可される機能のホワイトリストを作成します。

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)

% test.py foo 1
Running foo('1')
% test.py bar 2
Running bar('2')
% test.py baz 3
KeyError: 'baz'

上記は、コマンドがコマンドライン自体に入力されたときに機能します。コマンドが に入力されている場合は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

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))

これを処理する別のより洗練された方法は、コメントで言及されているように、 cmd モジュールを使用することです。

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 モジュールの使用方法の詳細については、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
于 2013-01-25T13:32:08.547 に答える
2

optparsepython 2.7以降は非推奨であり、とにかくargparseははるかに柔軟です。unutbu のアプローチは安全ですが、ホワイトリストを提供する場合は、どの機能が受け入れられるかをユーザーに知らせることをお勧めします

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

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

参考までに: 構文解析がそれほど複雑でない場合、docoptは非常に優れたパッケージのように見えます

于 2013-01-25T13:45:17.660 に答える
1

Python のoptparseモジュールを見てください。それはまさにあなたが必要とするものです:

http://docs.python.org/2/library/optparse.html

または、独自のカスタム opt-parser を作成することもできます (最小限ですが)。

def getopts(argv):
   opts = {}
   while argv:
      if argv[0][0] == '-': # find "-name value" pairs
         opts[argv[0]] = argv[1] # dict key is "-name" arg
         argv = argv[2:]
      else:
         argv = argv[1:]
   return opts

if __name__ == '__main__':
from sys import argv # example client code
myargs = getopts(argv)
# DO something based on your logic here

ただし、スクリプトを python 3 以降で実行する必要がある場合は、argparseモジュールを検討する必要があります。\

それが役立つことを願っています。

于 2013-01-25T13:25:02.863 に答える
1

sys.argvはどうですか?より高度なものについては、 argsparseをチェックしてください。optparse現在は減価償却されているようですが、この質問については多くの回答があります。

于 2013-01-25T13:18:16.367 に答える
0

optparseを見てください。これは、シェル スタイルのパラメーターを Python スクリプトに渡したり受け取ったりするのに役立ちます。

更新: どうやらoptparse現在は非推奨であり、argparseはコマンド ライン引数を解析するための優先オプションになりました。

于 2013-01-25T13:17:39.307 に答える
0
import sys

def main(arg):
    return arg

print main(sys.argv[1])

ここで、sys.argv[0] は実行中の .py ファイルであり、その後のすべてが各引数になります。リストの長さを確認し、それを繰り返し処理し、必要に応じてそれらを解析し、正しいものを各関数に渡すことができます

于 2013-01-25T13:20:36.977 に答える