SimplePrograms - Python Wiki
https://wiki.python.org/moin/SimplePrograms
の 8番目のプログラムは、表題から コマンドライン引数 と 例外処理 です。
# This program adds up integers that have been passed as arguments in the command line
import sys
try:
total = sum(int(arg) for arg in sys.argv[1:])
print ('sum =', total)
except ValueError:
print ('Please supply integer arguments')
# から command line まで1行でしたので、7行?しかないです。
Python でのコメントの仕方を1行目が示しています。
「Python におけるコメント文は、ハッシュ文字 # で始まり、物理行の終わりまで続きます。」
ですね。改行するとプロンプトが >>> になるので、継続行にも「 # 」を付けるようです。
>>> # comment-1
>>> # comment-2
>>> # comment-3
さて、import で sys モジュールをインポートすると、
「スクリプト名と引数を指定してインタプリタを起動した場合、スクリプト名やスクリプト名以後に指定した引数は、文字列のリストに変換されて sys モジュールの argv 変数に格納されます。 import sys とすることでこのリストにアクセスできます。」
となり、ここでは sys.argv を使っています。argv と言えば C言語由来でコマンドラインの引数を表しますが、Python も同じですね。
この場合、コマンドとして指定された引数を受け取るので、今までの対話型ではこうなってしまいます。
>>> import sys
>>> sum(int(arg) for arg in sys.argv[1:])
0
>>>
これでは、確認しようがないのでプログラムをファイルに保存してそちらを実行します。
8番目のプログラムを prog-008.py というファイルに保存して、python3 で実行すれば良さそうです。
$ python3 prog-008.py
sum = 0
$
$ python3 prog-008.py 1 2 3 4
sum = 10
$
予想通り、プログラムをコマンドとして実行すると引数が指定できて sys.argv を通してプログラムに渡されました。
$ python3 プログラムファイル このプログラムの引数1 このプログラムの引数2 .......
ですね。コマンドっぽくするには、bash なら同じディレクトリにシェルスクリプト prog-008.sh を作って、実行可能にできます。
$ cat prog-008.sh
#!/bin/bash
python3 prog-008.py $*
$
$ chmod u+x prog-008.sh
$
$ ./prog-008.sh 1 2 3 4
sum = 10
$
しかし、prog-008.py の先頭に bash のために python3 を指定することもできるので、こちらを使用するのが一般的でしょう。
まず which コマンドで Python3 のフルパス名を求めましょう。
$ which python3
/usr/bin/python3
$
なので、prog-008.py の1行目に次のものを挿入します。
#!/usr/bin/python3
もしかして、8番目のこのプログラムが7行なのは、この1行を挿入するためかもしれませんね。
このファイルを実行可能にすると、
$ chmod u+x prog-008.py
$
$ ./prog-008.py 1 2 3
sum = 6
$
となりました。pythonで作成されたプログラムは、Linux ではこんな感じで作成するのですね。
その時は、sys と argv を使用すると覚えます。
さて、 try: と except ValueError: は何でしょうか。これは、
https://docs.python.org/ja/3/tutorial/errors.html
の、「8.3 例外を処理する」に説明されています。
「まず、 try 節 (try clause) (キーワード try と except の間の文) が実行されます。
何も例外が発生しなければ、 except 節 をスキップして try 文の実行を終えます。」
だそうです。そのまま覚えましょう。
try: の下のインデントされた行を見てみます。
sys.argv[1:] は、引数配列(コマンド行そのもので、空白で区切ったもの)から部分的に要素を取り出してリストにするやり方のようです。
そこで、prog-008.py の try 節を、以下のようにした prog-008-01.py と、
さらに sys.argv を sys.argv[1:] にした prog-008-02.py を作成します。
try:
total = sys.argv
print (total)
$ ./prog-008-01.py 1 2 3
['./prog-008-01.py', '1', '2', '3']
$
$ ./prog-008-02.py a b c
['1', '2', '3']
$
ということで、sys.argv は、引数のリストでした。ここで sys.argv[0] はプログラム名ですから、
sys.argv[1] が1番目の引数、sys.argv[2] が2番目の引数 .... となるので、
[1:] の意味は、2つめ(0が先頭)以降の要素を表すので、sys.argv[1:] は引数全部を要素(文字列)にしたリストということですね。
また、int()ですが、
>> 1 + 2
3
>>> 1 + '2' # '2' は、数字からなる文字列です。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 1 + int('2')
3
>>>
つまり、数値しか使えない算術演算を実行するために、引数は文字列なのでint()を使って整数に変換するという意味ですね。
今回のプログラムは、引数をジェネレータ式を使って数値の複数要素からなるジェネレータオブジェクトにしてsum()で合計するわけです。
さて、引数が数値を表す文字列でなかったらどうなるでしょうか。
$ ./prog-008.py 1 2 3 4
sum = 10
$
$ ./prog-008.py 1 2 3 'abc'
Please supply integer arguments
$
引数が文字列なので int() で例外が発生したようです。すると、try節の残り
print ('sum =', total)
はスキップして、except ValueError: へ移動して、その後の、
print ('Please supply integer arguments')
を実行するわけですね。例外処理の方法が分かるプログラムでした。
8番目にしてこのような例外処理がでてきたので、この後のプログラムも凄そうです。
https://wiki.python.org/moin/SimplePrograms
の 8番目のプログラムは、表題から コマンドライン引数 と 例外処理 です。
# This program adds up integers that have been passed as arguments in the command line
import sys
try:
total = sum(int(arg) for arg in sys.argv[1:])
print ('sum =', total)
except ValueError:
print ('Please supply integer arguments')
# から command line まで1行でしたので、7行?しかないです。
Python でのコメントの仕方を1行目が示しています。
「Python におけるコメント文は、ハッシュ文字 # で始まり、物理行の終わりまで続きます。」
ですね。改行するとプロンプトが >>> になるので、継続行にも「 # 」を付けるようです。
>>> # comment-1
>>> # comment-2
>>> # comment-3
さて、import で sys モジュールをインポートすると、
「スクリプト名と引数を指定してインタプリタを起動した場合、スクリプト名やスクリプト名以後に指定した引数は、文字列のリストに変換されて sys モジュールの argv 変数に格納されます。 import sys とすることでこのリストにアクセスできます。」
となり、ここでは sys.argv を使っています。argv と言えば C言語由来でコマンドラインの引数を表しますが、Python も同じですね。
この場合、コマンドとして指定された引数を受け取るので、今までの対話型ではこうなってしまいます。
>>> import sys
>>> sum(int(arg) for arg in sys.argv[1:])
0
>>>
これでは、確認しようがないのでプログラムをファイルに保存してそちらを実行します。
8番目のプログラムを prog-008.py というファイルに保存して、python3 で実行すれば良さそうです。
$ python3 prog-008.py
sum = 0
$
$ python3 prog-008.py 1 2 3 4
sum = 10
$
予想通り、プログラムをコマンドとして実行すると引数が指定できて sys.argv を通してプログラムに渡されました。
$ python3 プログラムファイル このプログラムの引数1 このプログラムの引数2 .......
ですね。コマンドっぽくするには、bash なら同じディレクトリにシェルスクリプト prog-008.sh を作って、実行可能にできます。
$ cat prog-008.sh
#!/bin/bash
python3 prog-008.py $*
$
$ chmod u+x prog-008.sh
$
$ ./prog-008.sh 1 2 3 4
sum = 10
$
しかし、prog-008.py の先頭に bash のために python3 を指定することもできるので、こちらを使用するのが一般的でしょう。
まず which コマンドで Python3 のフルパス名を求めましょう。
$ which python3
/usr/bin/python3
$
なので、prog-008.py の1行目に次のものを挿入します。
#!/usr/bin/python3
もしかして、8番目のこのプログラムが7行なのは、この1行を挿入するためかもしれませんね。
このファイルを実行可能にすると、
$ chmod u+x prog-008.py
$
$ ./prog-008.py 1 2 3
sum = 6
$
となりました。pythonで作成されたプログラムは、Linux ではこんな感じで作成するのですね。
その時は、sys と argv を使用すると覚えます。
さて、 try: と except ValueError: は何でしょうか。これは、
https://docs.python.org/ja/3/tutorial/errors.html
の、「8.3 例外を処理する」に説明されています。
「まず、 try 節 (try clause) (キーワード try と except の間の文) が実行されます。
何も例外が発生しなければ、 except 節 をスキップして try 文の実行を終えます。」
だそうです。そのまま覚えましょう。
try: の下のインデントされた行を見てみます。
sys.argv[1:] は、引数配列(コマンド行そのもので、空白で区切ったもの)から部分的に要素を取り出してリストにするやり方のようです。
そこで、prog-008.py の try 節を、以下のようにした prog-008-01.py と、
さらに sys.argv を sys.argv[1:] にした prog-008-02.py を作成します。
try:
total = sys.argv
print (total)
$ ./prog-008-01.py 1 2 3
['./prog-008-01.py', '1', '2', '3']
$
$ ./prog-008-02.py a b c
['1', '2', '3']
$
ということで、sys.argv は、引数のリストでした。ここで sys.argv[0] はプログラム名ですから、
sys.argv[1] が1番目の引数、sys.argv[2] が2番目の引数 .... となるので、
[1:] の意味は、2つめ(0が先頭)以降の要素を表すので、sys.argv[1:] は引数全部を要素(文字列)にしたリストということですね。
また、int()ですが、
>> 1 + 2
3
>>> 1 + '2' # '2' は、数字からなる文字列です。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> 1 + int('2')
3
>>>
つまり、数値しか使えない算術演算を実行するために、引数は文字列なのでint()を使って整数に変換するという意味ですね。
今回のプログラムは、引数をジェネレータ式を使って数値の複数要素からなるジェネレータオブジェクトにしてsum()で合計するわけです。
さて、引数が数値を表す文字列でなかったらどうなるでしょうか。
$ ./prog-008.py 1 2 3 4
sum = 10
$
$ ./prog-008.py 1 2 3 'abc'
Please supply integer arguments
$
引数が文字列なので int() で例外が発生したようです。すると、try節の残り
print ('sum =', total)
はスキップして、except ValueError: へ移動して、その後の、
print ('Please supply integer arguments')
を実行するわけですね。例外処理の方法が分かるプログラムでした。
8番目にしてこのような例外処理がでてきたので、この後のプログラムも凄そうです。