Pythonには、いくつかの関数を定義するmodule myModule.pyと、いくつかのコマンドライン引数を受け取るmain()があります。
通常、このmain()はbashスクリプトから呼び出します。さて、すべてを小さなpackageに入れたいので、単純なbashスクリプトをPythonスクリプトに変えてパッケージに入れることができると思いました。
それで、実際にはどうすればmyModule.pyのmain()関数を呼び出すmain()関数から MyFormerBashScript.pyを呼び出すのか?それさえできますか? argumentsを渡すにはどうすればよいですか?
それは単なる機能です。それをインポートして呼び出します:
import myModule
myModule.main()
引数を解析する必要がある場合、2つのオプションがあります。
それらをmain()
で解析しますが、sys.argv
をパラメーターとして渡します(同じモジュール内の以下のすべてのコードmyModule
):
def main(args):
# parse arguments using optparse or argparse or what have you
if __== '__main__':
import sys
main(sys.argv[1:])
これで、他のモジュールからmyModule.main(['arg1', 'arg2', 'arg3'])
をインポートして呼び出すことができます。
main()
に、既に解析されたパラメーターを受け入れるようにします(ここでもmyModule
モジュールのすべてのコード):
def main(foo, bar, baz='spam'):
# run with already parsed arguments
if __== '__main__':
import sys
# parse sys.argv[1:] using optparse or argparse or what have you
main(foovalue, barvalue, **dictofoptions)
myModule.main(foovalue, barvalue, baz='ham')
をインポートして他の場所で呼び出し、必要に応じてpython引数を渡します。
ここでの秘Theは、モジュールがスクリプトとして使用されていることを検出することです。 pythonファイルをメインスクリプトとして実行すると(python filename.py
)import
ステートメントは使用されないため、pythonはそのモジュールを呼び出します"__main__"
。しかし、同じfilename.py
コードがモジュール(import filename
)として扱われる場合、pythonは代わりにモジュール名としてそれを使用します。どちらの場合も、変数__name__
が設定されており、それに対するテストにより、コードの実行方法がわかります。
Martijenの答えは理にかなっていますが、他の人には自明であるかもしれない重要なものが欠けていましたが、私には理解するのが困難でした。
Argparseを使用するバージョンでは、この行を本体に含める必要があります。
args = parser.parse_args(args)
通常、あなたが書くだけのスクリプトでargparseを使用しているとき
args = parser.parse_args()
parse_argsは、コマンドラインから引数を見つけます。ただし、この場合、メイン関数はコマンドライン引数にアクセスできないため、argparseに引数を伝える必要があります。
ここに例があります
import argparse
import sys
def x(x_center, y_center):
print "X center:", x_center
print "Y center:", y_center
def main(args):
parser = argparse.ArgumentParser(description="Do something.")
parser.add_argument("-x", "--xcenter", type=float, default= 2, required=False)
parser.add_argument("-y", "--ycenter", type=float, default= 4, required=False)
args = parser.parse_args(args)
x(args.xcenter, args.ycenter)
if __== '__main__':
main(sys.argv[1:])
このmytest.pyという名前を付けたと仮定すると、コマンドラインからこれらのいずれかを実行できます。
python ./mytest.py -x 8
python ./mytest.py -x 8 -y 2
python ./mytest.py
それぞれ返す
X center: 8.0
Y center: 4
または
X center: 8.0
Y center: 2.0
または
X center: 2
Y center: 4
または、別のpythonスクリプトから実行したい場合
import mytest
mytest.main(["-x","7","-y","6"])
返す
X center: 7.0
Y center: 6.0
場合によります。メインコードが次のようにif
で保護されている場合:
if __== '__main__':
...main code...
いいえ、自動変数__name__
に影響を与えることができないため、Pythonを実行させることはできません。
しかし、すべてのコードが関数内にある場合、可能になる場合があります。試して
import myModule
myModule.main()
これは、モジュールが__all__
で自身を保護する場合でも機能します。
from myModule import *
はmain
を表示しない場合があるため、モジュール自体をインポートする必要があります。
私もargparse
を使用する必要がありました。事は、parse_args
オブジェクトインスタンスのargparse.ArgumentParser
関数は、sys.args
からデフォルトで暗黙的に引数を取ります。 Martijnの行に続く回避策は、明示的にすることであるため、parse_args
に渡す引数を必要に応じて変更できます。
def main(args):
# some stuff
parser = argparse.ArgumentParser()
# some other stuff
parsed_args = parser.parse_args(args)
# more stuff with the args
if __== '__main__':
import sys
main(sys.argv[1:])
重要な点は、引数をparse_args
関数に渡すことです。後で、メインを使用するには、Martijnの指示どおりに実行します。
私が探していた答えはここに答えられました: python argparseをsys.argv以外の引数と一緒に使用するには?
main.py
およびparse_args()
がこの方法で記述されている場合、解析はうまく実行できます。
# main.py
import argparse
def parse_args():
parser = argparse.ArgumentParser(description="")
parser.add_argument('--input', default='my_input.txt')
return parser
def main(args):
print(args.input)
if __== "__main__":
parser = parse_args()
args = parser.parse_args()
main(args)
次に、main()
を呼び出し、別のpythonスクリプトでparser.parse_args(['--input', 'foobar.txt'])
を使用して引数を解析できます。
# temp.py
from main import main, parse_args
parser = parse_args()
args = parser.parse_args([]) # note the square bracket
# to overwrite default, use parser.parse_args(['--input', 'foobar.txt'])
print(args) # Namespace(input='my_input.txt')
main(args)
コマンドライン引数も渡そうとしていると仮定します。
import sys
import myModule
def main():
# this will just pass all of the system arguments as is
myModule.main(*sys.argv)
# all the argv but the script name
myModule.main(*sys.argv[1:])