Python3 の基礎

Python3 に関して参考になる資料等

今時のプログラミング言語は、公式ページのドキュメントが大変充実しています。 何らかのプログラミング経験者であれば、公式ページの Python 3 ドキュメントにある チュートリアルやリファレンスマニュアルを参考にすれば入門用としては十分なレベルの情報が得られるでしょう。

機械学習の分野では今や鳥を落とす勢いで人気を博している為、公式以外からも質の高い資料が多数発表されています。

主だったものを用語集の Python のところにまとめておきましたので参考にしてください。

Hello world

まず最初に、新しいプログラミング言語を学ぶ儀式として、 世界で最も有名なプログラムの一つである hello world の書き方を確認してみましょう。

Hello world は C 言語のバイブルである通称 K&R こと「 B.W.カーニハン / D.M.リッチー 著 プログラミング言語 C 」の一番最初に紹介されるプログラムです。 これに因んで多くのプログラミング言語では、チュートリアルの最初で hello world を表示させるプログラムの書き方を紹介しています。 一種の様式美と言ってもよいでしょう。

C言語の hello world

オリジナルであるC言語の hello world は リスト 88 の通りです。

リスト 88 C言語の hello world (hello.c)
#include <stdio.h>

main()
{
    printf("hello, world\n");
}

C言語はコンパイラ型の言語なので、プログラムを実行する前にソースコードをコンパイラと呼ばれるプログラムにかけることで、 CPU が直接解釈・実行可能な機械語のプログラムに翻訳しておく必要があります。 この作業をコンパイルと呼びます。 POSIX 環境ではC言語のコンパイラ(Cコンパイラ)として cc コマンドが用意されています。

C言語版 hello world のソースコードを保存してあるファイル hello.c を cc コマンドでコンパイルした後、 得られた実行ファイル a.out を実行した例を リスト 89 に示します。 1

hello.c をダウンロードしたフォルダを POSIX 環境で端末の作業ディレクトリにした状態で試してみましょう。

リスト 89 POSIX 環境におけるC言語版 hello world のコンパイルと実行例
$ # ソースコード(hello.c)をCコンパイラーでコンパイルして実行ファイル(a.out)を得る
$ cc hello.c
hello.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
    3 | main()
      | ^~~~
$ # 得られた実行ファイル(a.out)を実行する
$ ./a.out
hello, world
1

念の為補足しておきますが、見ての通り、コンパイル時に警告(warning)が出ています。 これはオリジナルの hello world では main() 関数の定義に必要な戻り値の型を省略していることが原因です。 この例では、コンパイルと実行に支障は出ていませんが、 警告が出る書き方を無視して放置しているとバグの発生原因になる可能性もあります。 原因を確認すると共に、警告が出ない書き方に修正するよう心がけてください。

Python3 の hello world

Hello world を Python3 で書くと リスト 90 のようになります。

リスト 90 Python3 の hello world (hello.py)
#!/usr/bin/env python3
print("hello, world")

Python はインタプリタ型の言語なので、ソースコードをインタプリタのコマンドにそのまま渡すことで即実行可能です。

Python3 版 hello world のソースコードが保存されたファイル hello.py を Python3 のインタプリタである python3 コマンドに渡して実行した例を リスト 91 に示します。

リスト 91 POSIX 環境における Python3 版 hello world の実行例
$ # ソースコード(hello.py)を Python3 インタプリタに渡して実行する
$ python3 hello.py
hello, world

ところで、 リスト 90 の 1 行目にある "#!/usr/bin/env python3" という記述に気付いた人はいるでしょうか? Python では "#" から行末までをコメントとして扱うためこの行はプログラムとして解釈されません。 一方 POSIX 環境の shell は実行属性の付与されたファイルの先頭が "#!" で始まっていると、 1 行目の 3 文字目以降に書かれている内容を、インタプリタのコマンドの指定として解釈する仕組みがあります。 この仕組み及び 1 行目の記述方法は shebang (シバン) と呼ばれています。

Python を始めとした UNIX 系のスクリプト言語の多くは、 "#" から行末までをコメントとして扱う点に共通性が認められます。 これはおそらく shebang の仕組みに根ざすところが大きいでしょう。

スクリプト言語のソースファイルに shebang と実行属性が設定されている場合、 ソースファイルを与えてインタプリタコマンドを実行せずとも、 ソースファイルを直接実行することが可能になります( リスト 92 )。

リスト 92 hello.py を直接実行した例
$ ./hello.py
hello, world

もし hello.py に実行属性が付与されてない場合、 リスト 93 または リスト 94 のような エラーになるでしょう。

リスト 93 hello.py を直接実行した例 (実行属性がない場合: 和文エラー表示)
$ ./hello.py
bash: ./hello.py: 許可がありません
リスト 94 hello.py を直接実行した例 (実行属性がない場合: 英文エラー表示)
$ ./hello.py
bash: ./hello.py: Permission denied

この場合、ls コマンドの -l オプションでファイルの属性に実行属性(x)が付与されているか確認すると共に、 chmod コマンドの +x オプションを用いてソースファイルに実行属性を与えます( リスト 95 )。

リスト 95 実行属性の確認と付与
$ # ファイル属性の確認
$ ls -l hello.py
-rw-rw-r-- 1 user group 45  5月 22 21:38 hello.py

$ # ファイルに実行属性を付与
$ chmod +x hello.py

$ # 再度ファイル属性の確認
$ ls -l hello.py
-rwxrwxr-x 1 user group 45  5月 22 21:38 hello.py

Python3 の REPL 環境で hello world

C言語にはない Python の特徴の一つとして、 REPL (Read-Eval-Print Loop) と呼ばれる対話型の実行環境があります。

コマンドライン引数を与えず、単独で python3 コマンド(リスト 96)を実行すると REPL 環境が起動します(リスト 97)。

リスト 96 Python3 の REPL 環境用のコマンド
python3
リスト 97 Python3 の REPL 環境が起動した状態
$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

ここにキーボードから print("hello, world") (リスト 98)と対話的に入力して [ENTER] キーを叩くと、 対話的に結果が得られます(リスト 99)。

リスト 98 Python3 の REPL 環境に入力する hello world
print("hello, world")
リスト 99 Python3 の REPL 環境で対話的に実行した hello world の結果
$ python3
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hello, world")
hello, world
>>>

REPL では shell と同じように history と呼ばれる機能が利用できます。 カーソルキーの上下で以前入力して実行した内容を呼び出すとともに編集、再実行が可能です。 何度も同じような命令を打つ必要はありません。

Jupyter notebook で hello world

Jupyter Notebook の起動 で少し紹介していますが、 Jupyter notebook も対話型のプログラミング環境なので、 REPL でやる場合とほぼ同じです。 ただし、Jupyter notebook では、 ブラウザ上で前後のコードブロックを行ったり来たりしながら、 その内容の編集や再実行が可能となっています。

試しに、コードブロックに print("hello, world") と入力して実行してみましょう (図 18)。

_images/fig_helloworld_ipynb.png

図 18 Jupyter notebook で hello world.

標準入出力とパイプ、リダイレクト

Python の input() や print() による入出力は 標準入出力と呼ばれる仕組みを利用しています。

標準入出力は POSIX 環境の使い方 で紹介した パイプラインリダイレクト で扱う事が出来るので、 Python 側のプログラムとしてファイル入出力を実装しなくても input() や print() からファイルに対する簡易的な入出力を行うことが可能です。

例えば、 リスト 90 の結果をファイルに保存するには リスト 100 のようにします(リスト 101)。

リスト 100 hello.py の出力をファイルへ保存する例
./hello.py > hello.txt
リスト 101 hello.py の出力をファイルへ保存する例実行結果
$ ./hello.py > hello.txt
$ cat hello.txt
hello, world

また、input() を持ちいてキーボードから入力したデータを処理する リスト 102リスト 103 のような プログラムがあったとします。

リスト 102 文字列の足し算 (stdio_001.py)
#!/usr/bin/env python3

a = input("a = ")
b = input("b = ")
print(f"a + b = {a + b}")
リスト 103 数値の足し算 (stdio_002.py)
#!/usr/bin/env python3

a = int(input("a = "))
b = int(input("b = "))
print(f"a + b = {a + b}")

これは、そのまま Jupyter notebook に貼り付ければ 図 19 のように実行可能です。

_images/stdio_001,002.ipynb.png

図 19 stdio_001.py と stdio_002.py の Jupyter notebook による実行結果

しかし、input() による入力は手で入力しなければなりません。

コマンドラインから実行する際も同様ですが、 パイプやリダイレクトを用いると input() や print() 等、標準入出力を前提としたプログラムの 入力を自動化したり出力をファイルに記録することが容易にできます ( リスト 104リスト 105リスト 106リスト 107、 )。

リスト 104 stdio_001.py へパイプラインを渡す例
echo -e "1\n2" | ./stdio_001.py
リスト 105 stdio_002.py へパイプラインを渡す例
echo -e "1\n2" | ./stdio_002.py
リスト 106 stdio_001.py へパイプラインを渡す例実行結果
$ echo -e "1\n2" | ./stdio_001.py
a = b = a + b = 12
リスト 107 stdio_002.py へパイプラインを渡す例実行結果
$ echo -e "1\n2" | ./stdio_002.py
a = b = a + b = 3

または、リスト 108 のようなデータファイルがあれば、 リスト 109 のようにファイルから標準入力へリダイレクト することも出来ます。

リスト 108 足し算用のデータファイル (stdio_001_in.txt)
1
2
リスト 109 stdio_001.py へリダイレクトを渡す例
./stdio_001.py < stdio_001_in.txt
リスト 110 stdio_001.py へリダイレクトを渡す例実行結果
$ ./stdio_001.py < stdio_001_in.txt
a = b = a + b = 12

input() の出力である "a = " や "b = " がちょっと邪魔ですが、 パラメータを外部ファイルとして用意して、結果をファイルに保存する等の ちょっとした用途に使えるでしょう。