[Python3 入門 9日目] 5章 Pyの化粧箱：モジュール、パッケージ、プログラム（5.1〜5.4）

#5.1 スタンドアローンプログラム

- テキストターミナル、またはターミナルウィンドウでPythonを実行している場合、Pythonプログラムの名前に続いてプログラムファイル名を入力する。

```py:test1.py
print("This stadalone program works!")
```

```console:結果
$ python test1.py
This stadalone program works!
```

#5.2 コマンドライン引数

```py:test2.py
import sys
print("Program arguments:",sys.argv)
```

```console:結果
$ python test2.py
Program arguments: ['test2.py']

$ python test2.py tra la la
Program arguments: ['test2.py', 'tra', 'la', 'la']
```

#5.3 モージュールとimport文

- **モジュール**はPythonコードをまとめたファイルである。
- 他のモジュールのコードはimport文で参照する。こうすると、インポートしたモージュールのコード、変数をプログラム内で使えるようになる。

##5.3.1 モジュールのインポート

- import文の最も単純な使い方はimport moduleという形式。ここでmoduleの部分は他のPythonファイルのファイル名から拡張子の.pyを取り除いたもの。
- import文を通り過ぎると、メインプログラムはmodule.というプレフィックスを付ける限り、module.pyに含まれる全ての部分にアクセスできるようになる。
- インポートされるコードが複数の場所で使われる場合には、関数の外でインポートすることを考えると良い。 

```py:メインプログラム
#reportモジュールをインポート
import report

description=report.get_description()
print("Today is weather:",description)
```

```py:report.py
#モジュール
#get_description()はPython標準のrandomモジュールからchoice関数をインポートしている。
def get_description():
    """プロと同じようにランダムな天気を返す"""
    from random import choice
    possibilities=["rain","snow","sleet","fog","sun","who knows"]
    return choice(possibilities)
```

```console:結果
$ python weatherman.py
Today is weather: fog

$ python weatherman.py
Today is weather: sun

$ python weatherman.py
Today is weather: fog
```


```py:書き換え可能
#randomモジュールから直接choice関数をインポートしている。
def get_description():
    """プロと同じようにランダムな天気を返す"""
    import random
    possibilities=["rain","snow","sleet","fog","sun","who knows"]
    return random.choice(possibilities)
```

```py
>>> import random
>>> def get_description():
...     possibilities=["rain","snow","sleet","fog","sun","who knows"]
...     return random.choice(possibilities)
... 
>>> get_description
<function get_description at 0x11035b950>
>>> get_description()
'who knows'
>>> get_description()
'who knows'
>>> 
```

##5.3.2 別名によるモジュールのインポート
- 別名を使ってインポートできる。

```py
import report as x

description=x.get_description()
print("Today is weather:",description)
```

##5.3.3 必要なものだけをインポートする方法

- Pythonではモジュールから一つ以上の部品だけをインポートすることができる。

```py:元の名前でインポート
from report import get_description
description = get_description()
print("Today is weather:",description)
```

```py:do_itでインポート
from report import get_description as do_it
description = do_it()
print("Today is weather:",description)
```

##5.3.4 モジュールサーチパス

- 使われるファイルは最初にマッチしたファイルである。そのため自分でrandomというモジュールを定義し、それが標準ライブラリよりも前のサーチパスに含まれていた場合、標準ライプラリのrandomにはアクセスできない。


```py
>>> for place in sys.path:
...     print(place)
... 

practice/lib/python37.zip
practice/lib/python3.7
practice/lib/python3.7/lib-dynload
usr/local/var/pyenv/versions/3.7.5/lib/python3.7
practice/lib/python3.7/site-packages
```

#5.4 パッケージ

- モジュールは**パッケージ**と呼ばれる階層構造に組織できる。
- sourcesディレクトリには以下の2つのファイルに加え、__init__.pyという名前のファイルが必要。中身は空で良いが、Pythonはこのファイルがあるディレクトリをパッケージとして扱うため。

```py:メインプログラム
#enumerate関数はインデックス番号、要素の順に値を取得できる。第二引数に1を指定することでインデックスを1に指定できる。
from sources import daily, weekly

print("Daily forecast:",daily.forecast())
print("Weekly forecast:")
for number, outlook in enumerate(weekly.forecast(),1):
    print(number, outlook)
```

```py:sources/daily.py
#モジュール1
def forecast():
    "偽の天気予報"
    return "like yesterday"
```

```py:sources/weekly.py
#モジュール2
def forecast():
    "偽の週間天気予報"
    return ["snow","more snow","sleet","freezing rain","rain","fog","hail"]
```

```console:結果
$ python weather.py
Daily forecast: like yesterday
Weekly forecast:
1 snow
2 more snow
3 sleet
4 freezing rain
5 rain
6 fog
7 hail
```

#感想

今日は風が冷たい1日でした。


######参考文献
「Bill Lubanovic著 『入門 Python3』(オライリージャパン発行)」