Pythonの書き方と環境構築

# 概要
Pythonの書き方、環境の作成方法について調べた事を記載しています。

# 前提
Windows10にPython3のインストールを行い、Eclipse(PyDev)を使ってコードを記述しています。

# インストーラーのダウンロード
[https://www.python.org/](https://www.python.org/)
からインストーラーをダウンロードする。

Menu ＞ Downloads ＞ Looking for Python with a different OS? Python for Windows
から最新バージョン（今回はWindows x86-64 executable installer）をダウンロードします。

# インストールとパスの設定
ダウンロードしたファイルを実行する。
今回は下記のようなフォルダ構成になっています。

```text:フォルダ構成
E:\
┗━usr\
　　┗━local\
　　　　┗━python\
　　　　　　┗━python36\
　　　　　　　　┣━DLLs\
　　　　　　　　┣━Scripts\
　　　　　　　　┗━...
```

「Add Python 3.6 to PATH」をチェックせずにインストールした場合は、
システム環境変数の`Path`に下記を追加します。
`E:\usr\local\python\python36`

# 確認
コマンドプロンプトで下記コマンドを実行します。
`python`
環境変数(Path)の設定が正常に出来ていた場合は下記のように表示され、対話形式で処理を実行できるようになります。

![sample02.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/f8845d70-7d47-144a-b523-a3ae6474df6a.jpeg)

「Hello World」を出力してみます。
![sample03.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/253b8c84-7699-d118-f642-011ecfbb1341.jpeg)

# PyDevプラグインのインストール
Eclipse(4.7)を使う事が多いので、試しにPyDevプラグインをEclipseにインストールしてみました。
Eclipseマーケットプレースから`PyDev`を検索してインストールします。
![sample04.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/487f677f-5896-de22-71a1-19d6916ea947.jpeg)

Eclipseを再起動してから、ウィンドウ ＞ 設定 ＞ PyDev ＞ Pythonインタープリター ＞ 新規で下記を登録します。
インタープリター名：Python36(任意の名前)
インタープリター実行可能ファイル：E:\usr\local\python\python36\python.exe

# Hello Worldを表示させるプログラムを作成
１．パッケージエクスプローラを右クリック ＞ 新規 ＞ その他 ＞ PyDev ＞ Pydevプロジェクトを選択
２．ソースフォルダ(src）を作成して、その直下にPydevモジュール（`gyunyu.py`）を作成
　　※今回はEmptyなテンプレートでモジュールを作成

```test:フォルダ構成
gyunyu_python\
┗━src\
　　┗━gyunyu.py
```

３．`gyunyu.py`に下記を記述

```python:gyunyu.py
print("Hello World")
```

４．`gyunyu.py`を右クリック ＞ 実行 ＞ Python実行を選択すると下記のように出力されます。
![sample05.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/b091a6ad-8705-db9a-ba8d-aaa079c3cd5d.jpeg)

# 変数への代入と標準出力
・変数への代入
　下記のように記述することで変数に値を代入することができます。
　`変数名 = 値`

・標準出力
　`print`関数を使う事で値を出力する事ができます。
　`print("出力したい文字列")`

```python:gyunyu.py
ichigo = "いちご"
print(ichigo)

#複数の変数の値を出力
coffee = "コーヒー"
gyunyu = "牛乳"
print(coffee, gyunyu)

#出力する値の区切り文字を空白にする
coffee = "コーヒー"
gyunyu = "牛乳"
print(coffee, gyunyu, sep="")

#改行なし
melon = "メロン"
print(melon, end="")
print(gyunyu)
```

`sep`オプション：複数の値を出力する場合の区切り文字を指定する（デフォルトは半角スペース）
`end`オプション：最後に出力される値の末尾に設定する文字列を指定する（デフォルトは改行文字）

![sample06.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/015f0080-1f6b-ae6f-9308-e913148bf9d1.jpeg)

# リストと繰り返し
・リスト
　下記のように記述することでリストオブジェクトを作成することができます。
　`変数名 = [要素,要素,...]`

・`for`文、`while`文を用いる事で繰り返し処理を行うことができます。

```
　for 変数 in オブジェクト:
　　　処理
```

```
　　while 条件式:
　　　処理
```

```python:gyunyu.py
gyunyu = ["コーヒー牛乳", "いちご牛乳", "めろん牛乳"]

for name in gyunyu:
    print(name)

num = 0
while num < len(gyunyu):
    print(gyunyu[num])
    num += 1
```

# 条件分岐
`if`文を用いる事で条件に応じて処理を分ける事ができます。

```
if 条件式1:
　条件式1がTrueだった時に実行する処理
elif 条件式2:
　条件式2がTrueだった時に実行する処理
else:
　条件式1と2に該当しなかった時に実行する処理
```

`elif`と`else`は省略可能で、条件分岐として必要な時だけ記述します。
条件式1に該当した場合、条件式2と`else`の処理は実行されません。

```python:gyunyu.py
gyunyu = ["コーヒー牛乳", "いちご牛乳", "めろん牛乳", "れもん牛乳"]

for name in gyunyu:
    if name == "コーヒー牛乳":
        print(name + "は100円です")
    elif name == "いちご牛乳":
        print(name + "は120円です")
    elif name == "めろん牛乳":
        print(name + "は140円です")
    else:
        print(name + "は売り切れです")
```

![sample07.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/14473476-1e8a-27e0-36b0-d0fb0dad660c.jpeg)

# タプルオブジェクト
下記のように記述することでタプルオブジェクトを作成する事ができます。
`変数名=(要素,要素,...)`

要素が1つしかないタプルオブジェクトを作成する場合は、カンマを要素の後ろにカンマを記述する。
`変数名=(要素,)`

```python:gyunyu.py
coffee = ("コーヒー牛乳") #strオブジェクトを()で囲んだだけと認識される
print(type(coffee))

ichigo = ("いちご牛乳",) #タプルオブジェクトと認識される
print(type(ichigo))

etc = ("めろん牛乳", "れもん牛乳", "ばなな牛乳")
for name in etc:
    print(name)
```

![sample08.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/fef1fe82-6430-97d8-b2aa-c6ef47015c59.jpeg)

タプルオブジェクトは、オブジェクト生成後に要素の変更・追加・削除が出来ない。
しかし、`+=`演算を行うことで要素の追加が出来たように見せかける事はできます（別オブジェクトとして生成される）。

```python:gyunyu.py
lemon = ("れもん牛乳",)
print(lemon, id(lemon))

gyunyu = lemon
print(gyunyu, id(gyunyu), gyunyu is lemon)

ichigo = ("いちご牛乳",)
print(ichigo, id(ichigo))

gyunyu += ichigo
print(gyunyu, id(gyunyu), gyunyu is lemon, gyunyu is ichigo)
```

![sample09.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/637bf624-10e0-5a23-0714-bfd3f442728a.jpeg)

# 辞書オブジェクト
下記のように記述する事で辞書オブジェクトを作成する事ができます。
`変数名={キー:値, キー:値,...}`

```python:gyunyu.py
gyunyu = {"コーヒー牛乳":"100円", "いちご牛乳":"120円"}

for key, val in gyunyu.items():
    print(key, val, sep="=")
```

![sample10.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/1ebc57d0-4b00-8ed3-23ed-636d21f51b3a.jpeg)

# 関数
下記のように記述する事で関数を作成する事ができます。

```
def 関数名(引数,引数,...):
  処理
```

```python:gyunyu.py
def printout(data):
    for key, val in data.items():
        print(key, val, sep="=")

printout({"コーヒー牛乳":"100円", "いちご牛乳":"120円"})
```

## 可変長引数
下記のように記述する事で、引数の数が固定ではなく可変個な関数を作成する事ができます。

```
def 関数名(引数1,引数2,*引数,**引数):
  処理
```
`*引数`：タプルオブジェクトとして値を受け取る
`**引数`：辞書オブジェクトとして値を受け取る

```python:gyunyu.py
def printout(melon, *milk, **gyunyu):
    print(melon)
    
    for name in milk:
        print(name)
        
    for key, val in gyunyu.items():
        print(key, val, sep="は")

printout("めろん牛乳は売り切れ", "れもんミルク", "ばななミルク", コーヒー牛乳="100円", いちご牛乳="120円")
```
![sample11.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/9cbac09c-49bf-5e62-3879-21290fc4c724.jpeg)

## デフォルト値
下記のように記述する事で、引数にデフォルト値を持たせる事ができます。

```
def 関数名(引数=デフォルト値):
  処理
```

```python:gyunyu.py
def printout(gyunyu="コーヒー牛乳"):
    print(gyunyu)

printout()
printout("いちご牛乳")
```
![sample12.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/69d16852-23db-fd18-5f52-660760821934.jpeg)

## キーワード引数
引数を指定して関数に値を渡すことができます。

```python:gyunyu.py
def printout(coffee, gyunyu):
    print(coffee, gyunyu)

printout(coffee="コーヒー", gyunyu="牛乳")
printout(gyunyu="牛乳", coffee="コーヒー")
```
![sample13.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/658d02b2-13c2-ef34-0884-d29b52756625.jpeg)

# クラス
下記のように`class`キーワードを用いる事で、クラスを作成する事ができます。

```
class クラス名:
  処理
```

クラス内に関数を作成する場合、関数の第一引数にクラスのインスタンスオブジェクト`self`を指定する必要があります。
`import`を使って別モジュール（今回はgyunyu.py）を読み込んでいます。

```python:gyunyu.py
class Coffee:
    def printout(self):
        print("コーヒー牛乳")
```

```python:main.py
import gyunyu

coffee = gyunyu.Coffee();
coffee.printout()
```

## コンストラクタ
インスタンス生成時に自動的に呼び出される関数（コンストラクタ）は、
下記のように`__init__`という名前の関数を作成する事で実装できます。

```python:gyunyu.py
class Coffee:
    def __init__(self):
        print("本日のお勧め商品")
    def printout(self):
        print("コーヒー牛乳")
```

```python:main.py
import gyunyu

coffee = gyunyu.Coffee();
coffee.printout()
```

![sample14.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/2d9ca972-83b5-f3c3-5015-28b1752070db.jpeg)

## デストラクタ
インスタンスが不要になって削除される時に自動的に呼び出される関数（デストラクタ）は、
下記のように`__del__`という名前の関数を作成する事で実装できます。

```python:gyunyu.py
class Coffee:
    def __del__(self):
        print("完売")
    def __init__(self):
        print("本日のお勧め商品")
    def printout(self):
        print("コーヒー牛乳")
```

```python:main.py
import gyunyu

coffee = gyunyu.Coffee();
coffee.printout()
```

![sample15.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/26d46850-f3ea-1722-61f2-31d818c832c5.jpeg)

## 継承

下記のように記述する事で他のクラスを継承する事ができます。

```
class クラス名(継承したいクラス1,継承したいクラス2,...):
  処理
```

```python:gyunyu.py
class Coffee:
    def __init__(self):
        print("本日のお勧め商品")
    def __del__(self):
        print("完売")
    def printout(self):
        print("コーヒー牛乳")

class Ichigo(Coffee):
    def printout(self):
        print("いちご牛乳")
```

```python:main.py
import gyunyu

ichigo = gyunyu.Ichigo();
ichigo.printout()
```

![sample16.jpg](https://qiita-image-store.s3.amazonaws.com/0/206289/a0cd3b75-7fe8-18d7-f9c5-4db1843c7a5f.jpeg)

Ichigoクラスの`printout`は、親クラス(Coffeeクラス)の`printout`をオーバーライドしています。

## importしたモジュールに別名を付ける
`as`キーワードを用いることで、importしたモジュールに別名を付ける事が出来ます。

```python:main.py
import gyunyu as milk

ichigo = milk.Ichigo()
ichigo.printout()
```

## 一部の関数、クラスだけを読み込む
`from`キーワードを使う事で、指定した関数、クラスだけを読み込む事が出来ます。
また、モジュール名.クラス名ではなくクラス名のみで利用出来るようになります。

```python:main.py
from gyunyu import Ichigo

ichigo = Ichigo();
ichigo.printout()
```

# 参考
[Python入門](https://www.pythonweb.jp/tutorial/)