Pythonの基本構文メモ

## 特徴

- 動的型付言語: 変数を定義するときに、データ型をあらかじめ宣言する必要なし
- 関数を「値」として扱える: 関数を変数に代入したり、関数を他の関数の引数に渡すことができる（第一級関数（ファーストクラスオブジェクト））
- 自動的に型変換が行われない
- コメントは、`#`を使う
- インデントはスペース4つが推奨

## 変数と定数

- 関数の外で作った変数 => グローバル変数
- 関数の中で作った変数 => ローカル変数
- 変数だけの宣言はできない

```python
color # エラー
color = 'red' # OK
```
- pythonに「定数」はない: 値を変更しないように気をつけて、定数として使うしかない。大文字にするなどルールを作るとよい

## 制御文

- switch文がない
- if文、elif文、else文を使う

```python
if color == 'red':
    print('赤')
elif color == 'blue':
    print('青')
else:
    print('黄')
```

- for文

```python
lists = ['赤', '青', '黄']
for list in lists:
    print(list)
```

## 関数

- `def`を使う
- 関数に`return`がない場合は、`None`を返す
- インデントが解除されたところで、定義が終了

``` python
def en2ja(color):
    if color == 'red':
        return '赤'
    elif color == 'blue':
        return '青'
    else:
        return '存在しません'

print(en2ja('red')) # '赤'
```

## データの集合体

- pythonでは配列を「リスト」と呼ぶ

```python
lists = ['赤', '青', '黄']
```
- keyでデータを管理する集合体は「辞書」と呼ぶ

```python
colors = { red: '赤', bule: '青', yellow: '黄' }
```

- 「タプル」という集合体がある。タプルは中身を変更できないリストのようなもの。`()`をつけなくてもOKだが、明示的にタプルを示すために`()`をつける

```python
colors = ('赤', '青', '黄')
```

- タプルは、たとえば関数から複数の値を返す時などに使われる

```python
def getColors():
    return ('赤', '青', '黄')

('red', 'blue', 'yellow') = getColors()
```

- タプルを使うとこういうこともできる

```python
a = '赤'
b = '青'

(a, b) = (b, a) # aは'青'、bは'赤'
```

- 「集合」という集合体がある。集合は、重複を認めないデータの順不同な集合体のこと

```python
colors = {'赤', '青', '青'}
print(colors) # {'赤', '青'}
```

- リストにおけるデータの追加は`append`メソッド、削除は`del`メソッド、または`pop`メソッドを使う

```python
# 追加
colors.append('緑') # 末尾に'緑'が追加される

# 削除
del colors[0] # 0番目のデータが削除される
colors.pop() # 末尾のデータが削除される
```

- 辞書におけるデータの追加は直接keyとvalueを指定し、削除は`del文、または`pop`メソッドを使う

```python
# 追加
colors['green'] = '緑' # keyが'green'、valueが'緑'のデータが追加される

# 削除
del colors['green'] # keyが'green'のデータが削除される
colors.pop('green') # keyが'green'のデータが削除される
```

- 辞書を一括処理したい場合は`for`文を使う

```python
for k, v in colors.items():
    print(k, v)
```

## クラス

- pythonでは、クラス自体もオブジェクト
- インスタンスメソッドの第一引数にはインスタンス自身を表す`self`を必ず指定。ここは`this`でも何でも良いが`self`にするのが慣例
- いわゆるコンストラクタは、初期化メソッド`__init__`を使う

```python
class Color:
    def __init__(self, color):
        self.color = color
    def showColor(self):
        return self.color

red = Color('red')
print(red.showColor()) # => 'red'
```

- 継承も可能

``` python
class Parent:
    def __init__(self, color):
        self.color = color
class Child(Parent):
    def __init__(self, color):
        super().__init__(color)
    def showColor(self):
        return self.color
```

## 正規表現

- 正規表現を扱うモジュール`re`が用意されている
- `match`メソッド: 適合した場合は、`Match`オブジェクトを返す。適合しなかった場合は、空を返す

```python
import re
m = re.match('py(thon)?3', 'python3')
```

- `search`メソッド: 文字列内に適合部分があるか探して判定する

```python
import re
m = re.search('py(thon)?3', 'python3')
```

- `finditer`メソッド: 文章中にある適合する文字列をすべて列挙する

```python
import re
rob = re.compile('py(thon)3')
originalString = 'python3をpy3と表記しました'
for m in rob.finditer(originalString):
    print(m.group)
```
- `sub`メソッド: 文章中にある適合する文字列を任意の文字列に置き換える

```python
import re
rob = re.compile('py(thon)3')
originalString = 'python3をpy3と表記しました'
print(rob.sub('パイソン', originalString)) # パイソンをパイソンと表記しました
```

## ファイルの入出力

- `open`関数を使ってファイルの新規作成、読み書きを行う
- 引数でファイル名や「読むのか、書くのか」指定
- 第二引数に`w`を指定すると、書き込みが行える

```python
file = open('samplefile.txt', 'w')
file.write('Hello¥nWorld') # 改行は¥n
file.close() # ファイルを閉じる
```

- 第二引数に`r`を指定すると、読み込みが行える
- 第二引数は省略可能で、省略すると`r`を指定したことになる

```python
file = open('samplefile.txt', 'r')
readString = file.read()
print(readString)
file.close() # ファイルを閉じる
```

- 第二引数に`a`を指定すると、追記が行える

```python
file = open('samplefile.txt', 'a')
file.write('Hello¥nPython') # 改行は¥n
file.close() # ファイルを閉じる
```
- 日本語を扱う場合は、引数に文字コードを指定すると確実

```python
file = open('samplefile.txt', 'a', encoding='utf-8', errors='ignore')
file.write('ハロー¥nパイソン') # 改行は¥n
file.close() # ファイルを閉じる
```
- csvファイルを扱う場合は、`csv`モジュールを使う

```python
with open('sample.csv', encoding='utf-8') as csvfile:
    csvreader = csv.reader(csvfile)
    next(csvreader)

    for members in csvreader:
        # 処理書く
```

- withは処理が完了したときに自動的にファイルを閉じる

# コピー

- 参照コピー: 代入する

```python
obj1 = ['red', ['blue', 'yellow']]
obj2 = obj1
```

- 浅いコピー（Shallow Copy）: `copy`モジュールの`copy`メソッドを使う

```python
import copy
obj1 = ['red', ['blue', 'yellow']]
obj2 = copy.copy(obj1)
obj2[1].append('green')
print(obj1) # ['red', ['blue', 'yellow', 'green']]
```

- 深いコピー（Deep Copy）: `copy`モジュールの`deepcopy`メソッドを使う

```python
import copy
obj1 = ['red', ['blue', 'yellow']]
obj2 = copy.deepcopy(obj1)
obj2[1].append('green')
print(obj1) # ['red', ['blue', 'yellow']]
```