Pythonを始めよう！ 〜②文法編〜


# 概要

[前回](http://qiita.com/gcfuji/items/199f6e8fe76a2f5547d9)の環境構築編の続きです。
今回はPythonの文法をざざっと見ていきます。

# Pythonの特徴

Pythonは、「シンプルで習得がしやすいオブジェクト指向言語」と呼ばれています。

Pythonは古くからプログラミング学習用言語として使われていますが、
最近は、GoogleAppEngineとして使われていたり、機械学習やデータ操作系のプラグインが豊富でかなり注目されています。
(日本では、そこまで目立ってはいないですが、海外では大人気らしい。)

[公式サイト](https://www.python.org/)

今回は、広く使われているPythonの2.7.xを使って文法を復習したいと思います。
(2.7.12を使います。)

# Pythonの文法

## セミコロンは非推奨

Pythonの文法では文末のセミコロンは非推奨です。
(次回以降で解説するpep8で定義されています。)
文末は改行で表現します。

## コメント

\#でコメントできます。

## 日本語文字を扱う

Pythonでコード上に日本語文字をいれると以下のエラーが吐かれます。

```python
  File "index.py", line 2
SyntaxError: Non-ASCII character '\xe3' in file index.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for
details
```

コード上で日本語を扱うときは、UTF-8を明示的に宣言する必要があります。

```python
# coding: UTF-8
# 上記で、コード上で日本語が使えるよ
print 'hello' # こんにちはと挨拶するよ
```
## 変数

特になんの接頭語もなく宣言できます。

```python
msg = 'hello from gemcook'

print msg
```

## データ型

Pythonで扱えるデータ型は以下となります。

- 数値
- 文字
- 真偽値(True/False)
- None
- 関数・オブジェクト
- 要素が並んだもの
	- 文字列(文字が並んだもの)
	- リスト(データが並んだもの(配列))
	- タプル(データが並んだもの(変更ができない))
	- セット(データが並んだもの(重複を許さない))
	- ディクショナリ(key-valueで管理)

### 数値型

#### 小数と整数の演算

小数と整数を演算すると、小数になります。

#### 切り捨ての整数

整数同士を割り算した場合、切り捨ての割り算結果がでます。

```python
print 10 / 3  # 3
```

小数も出したければ、以下の様にすれば良いです。

```python
print 10 / 3.0  # 3.3333333333
```

### 文字列

#### 日本語文字列を出力する場合

文字列の先頭に「u」（unicode)をつけて出力する。
(uを付けないと、文字列検索時に正しい結果が得られません。)

```python
print 'hello' + 'world'  # helloworld
print u'は' *5 # ははははは
```

#### エスケープ文字

\\で記述します。

```python
print 'It\'s a pen!'
```

#### 改行やエスケープが多い時

'''と'''で囲むとその範囲は改行したら改行、強制エスケープとなります。

```python
print '''
<html lang="ja">
    <body>
    </body>
</html>
'''
```

#### 文字列に関する命令

```python
s = 'abcdefghi'

print len(s) # 9
print s.find('c') # 2(存在しなければ-1を返します)

print s[2] # c
print s[2:5] # cde(5番目の1つ前までを返す)
print s[2:] # cdefghi
print s[:5] # abcde
print s[2:-1] # cdefgh(一番最後の文字の1つ前までを返す)
```

#### 数値と文字の変換

JSなど他の言語で、数値っぽい文字は自動的に数値に変換してくれたりします。
('1'は1と判断)

Pythonは自動で型変換を行わない為、明示的に型変換を行う必要があります。

```python
print 5 + '5' # エラーとなる。
```

整数に変換したい場合は、以下の様にする。

```python
print 5 + int('5') # 10
```

文字列に関しも同じである。

```python
age = 20

print 'i am ' + str(age) + ' years old'
```

### リスト型

他の言語では配列と呼ばれるものにあたる。

```python
sales = [
    255,
    100,
    353
]
```

リストの中身はどんな型の要素でも代入可能である。

```python
sales = [
    255,
    100,
    353,
    'apple'
]
```

リストに関しても、文字列と同じ様な命令を使う事ができる。

```python
sales = [
    255,
    100,
    353,
    'apple'
]

sales2 = [
	500,
	'orange'
]

print sales # [255, 100, 353, 'apple']

print sales * 2 # [255, 100, 353, 'apple', 255, 100, 353, 'apple']

print sales + sales2 # [255, 100, 353, 'apple', 500, 'orange']

print len(sales) # 4

print sales[3] # 'apple'

sales[2] = 250

print sales # [255, 100, 250, 'apple']
```

存在チェックの命令もある。

```python
sales = [
    255,
    100,
    353,
    'apple'
]

print 100 in sales # True
```

数字の連番のリストを作る命令もある。

```python
print range(3) # [0, 1, 2]

print range(1, 3) # [1, 2]

print range(3, 10, 2) # [3, 5, 7, 9]
```

#### リスト型の便利な命令

listはリスト型の変数、strは文字列型の変数とする。

- list.sort()
	- リストを小さい順に置き換える。
- list.reverse()
	- リストの順番を逆にする
	- 大きい順に並べるわけではない。
- str.split([区切り文字])
	- 文字を区切り文字で区切った配列を返してくれる。

```python
d = '2013/12/15'

print d.split('/') # [2013, 12, 15]
```

- str.join(list)
	- strの文字列でlistの文字を区切って文字列を返す。

```python
list = ['a', 'b', 'c']
print string.join(list)
```

### タプル型

タプルは基本はリストと同じです。
ただし、要素の変更ができないという特徴があります。

命令も配列と同じものが使えます。

- len
- in
- sort
- reverse
- split
- join

```python
tuple1 = (2, 5, 8)
tuple2 = (5, 5, 5)

print tuple1 + tuple2 # (2, 5, 8, 5, 5, 5)

print 2 in tuple2 # True

tuple1[2] = 10 # これはエラーになる。
```

#### タプルとリストの相互変換

文字列と数値の変換と同じで型変換命令を使う事で、柔軟にタプルとリストを切り替える事が可能です。

```python
array = [
    'dog',
    'cat',
    'tiger'
]

print array # ['dog', 'cat', 'tiger']

tupleChange = tuple(array)

listChange = list(tupleChange)

print tupleChange # ('dog', 'cat', 'tiger')
print listChange # ['dog', 'cat', 'tiger']
```


タプルを使う意味としては、明示的に変更できないデータだよと教える事のほかに、
処理速度の向上にもつながります。

タプルが利用できるタイミングでは、タプルを利用する様にしましょう。

### セット(集合型)

セットもリストやタプルと同じで、データが並んだものですが、
重複を許さないという特徴があります。

集合型と呼ばれている様に集合の計算を行うことができます。

#### セットの作り方

```python
a = set([1, 2, 3])
b = set([3, 4, 5])
```

また、重複しているデータは無視されます。

```python
print set([1, 2, 3, 3, 3, 4, 5]) # set([1, 2, 3, 4, 5])
```

#### 集合の計算

```python
# coding: UTF-8

a = set([1, 2, 3, 6])
b = set([3, 4, 5, 7])

# 差集合(aにあってbにないもの)
print b - a # set([1, 2, 6])

# 和集合(aとbにあるもの)
print a | b # set([1, 2, 3, 4, 5, 6, 7])

# 積集合(aとbで重複しているもの)
print a & b # set([3])

# aとbのどちらかにしかないもの
print a ^ b # set([1, 2, 4, 5, 6, 7])
```

### ディクショナリ型

JSでいうところのオブジェクトです。
Swiftの辞書型の方がイメージが近いと思います。

```python
mugiwara = {
    'luffy': 100000000,
    'zoro': 77000000
}

print mugiwara # {'zoro': 77000000, 'luffy': 100000000}
```

注意点としては、出力する要素は順不同であるという事です。

代入や取得に関しては、リストなどと変わりません。

```python
mugiwara = {
    'luffy': 100000000,
    'zoro': 77000000
}


print mugiwara['luffy'] # 100000000

mugiwara['zoro'] = 120000000

print mugiwara # {'zoro': 120000000, 'luffy': 100000000}
```

in命令でkeyの存在チェックも行えます。

```python
mugiwara = {
    'luffy': 100000000,
    'zoro': 77000000
}

print 'luffy' in mugiwara # True
```

#### ディクショナリ型のメソッド

ディクショナリ型ならではのメソッドです。

```python
mugiwara = {
    'luffy': 100000000,
    'zoro': 77000000
}

# keyの一覧を取得する。
print mugiwara.keys() # ['zoro', 'luffy']
# valueの一覧を取得する。
print mugiwara.values() # [77000000, 100000000]
# key-valueの一覧を取得する。
print mugiwara.items() # [('zoro', 77000000), ('luffy', 100000000)]
```

### 文字列型にデータを組み込む方法

わざわざ型変換を行わずとも、文字列型に他の型を埋め込む事も可能です。

```python
a = 3000000000
b = 1.234
c = 'luffy'
d = {
    'choppa': 50,
    'usoppu': 300000000
}

# 整数値を組み込む
print 'decimal: %010d' % a # 3000000000
# 小数値を組み込む
print 'float: %.1f' % b # 1.2
# 文字列を組み込む
print 'name: %s' % c # luffy
# 辞書型を組み込む
print 'berry: %(choppa)d' % d # 30000000
# 複数の値を組み込む
print '%s: %d' % (c, a) # luffy: 300000000
```

#### 整数値

- %dで表します(decimal)
	- 前に桁を入れる事でその桁数で表示できます。
	- 桁数の前に0を入れる事で0埋めできます。

#### 小数値

- %fで表します(float)
	- 前に.Xといれる事で、小数点以下の桁数を指定できます。

#### 文字列

- %sで表します(string)

#### 辞書型

- %([keyName])[valueの型の文字]で表します。

#### その他

- 複数の値を代入する事も可能です。
	- その際には、()で囲みます。

### 型チェック

Pythonの型チェックは以下の通りです。

```python
score = 70

print type(score) # <type, int>
```

また、Ture/Falseで返す方法もあります。

```python
score = 70

print isinstance(score, int) # True
print isinstance(score, str) # False
```

## 条件分岐

いつも通りifを使う。
条件式の()は不要です。
条件判定後の処理はインデントで字下げして表現します。

```python
# coding: UTF-8

score = 70

if 60 < score < 80:
    print 'ok' # 'ok'
```

### 比較演算子

あるある比較演算子です。

- <
- >
- <=
- >=
- ==
- !=
- is(インスタンスの同一性をチェック(値が一緒でもFalse))
- is not(インスタンスの同一性をチェック(値が違っていてもFalse))

### 論理演算子

論理演算子はより直感的になっています。
(JSなら &&, ||, !)

- and
- or
- not

### if else文

if else文もほぼ他の言語と変わりません。
elifだけが少し特徴的なので覚えておきましょう。

```python
score = 70

if int(score) > 60:
    print 'ok'
elif score > 40:
    print 'soso'
else:
    print 'ng'
```

### 1行で条件分岐

たいていの言語で、条件分岐を1行で描く方法が存在します。
(JSの三項演算子など)

Pythonの１行で条件分岐は少しトリッキーですが、
シンプルなコードを書く為にも丸暗記してしまいましょう。

```python
score =70

print 'ok' if score > 60 else 'ng'
```

## 繰り返し

for文が使えます。
以下が構文となります。

### リスト型のループ

```python
sales = [13, 3523, 31, 238]
result = 0

for sale in sales:
    result += sale
else:
    print result
```

else以下は、繰り返しが終了した際に、一度だけ実行する処理となります。

#### range()

単純に数値の連番を表示した場合は、range()が利用できる。

```python
for i in range(10):
    print i # 0 1 2 3 4 5 6 7 8 9 
```

#### continueとbreak

ループ処理を途中でスキップしたり、終了したりする時は、continueとbreakを使います。

```python
for i in range(10):
	if i == 3:
		continue
	elif i == 5:
		break
```

### 辞書型のループ

辞書型のループはiterXXXX()関数を利用します。

```python
# coding: UTF-8

mugiwara = {
    'luffy': 300,
    'zoro': 100,
    'sanji': 50
}

# key, values両方取得する。
for key, value in mugiwara.iteritems():
    print 'key: %s, value: %d' % (key, value)

# keyのみ取得する。
for key in mugiwara.iterkeys():
    print key

# valueのみ取得する。
for value in mugiwara.itervalues():
    print value
```

### whileループ

whileループもあります。

```python
# coding: UTF-8

n = 0

while n < 10:
    print n
    n += 1
else:
    print 'finish'
```

## 関数

普通の関数です。
複数の処理をまとめて登録しておきます。

defキーワードを利用します。

文法ルールとして(pep8)、関数を定義する際は、2行blank行を作って下さい。

```python
# coding: UTF-8


def sayHello():
    print 'hello'

sayHello()
```

### 引数

もちろん引数を取ることも可能です。

```python
# coding: UTF-8


def sayHello(name, num):
    print 'hello, %s.' % name * num

sayHello('Luffy', 2) # hello, Luffy.hello, Luffy.
```

#### 引数の初期化

登録側で=で初期値を設定します。
(pep8では、間位にスペースをとりません。)

```python
# coding: UTF-8


def sayHello(name, num=3):
    print 'hello, %s.' % name * num

sayHello('Luffy') # hello, Luffy.hello, Luffy.hello, Luffy.
```

#### 引数の指定

実行側で引数の指定を明示的に行うことも可能です。

```python
# coding: UTF-8


def sayHello(name, num=3):
    print 'hello, %s.' % name * num

sayHello('Luffy') # hello, Luffy.hello, Luffy.hello, Luffy.
sayHello(num=2, name='Zoro') # hello, Zoro.hello, Zoro.
```

### return文

登録側でreturn命令を使えば、単純な値として、関数の結果を返せます。

```python
# coding: UTF-8


def sayHello(name='no name'):
    return 'hello, %s' % name

print sayHello(name='Nami')
```

### 空関数の定義

とりあえず関数の実体のみ定義して、中身の処理は後で記述したい場合があると思います。
そんなとき他の言語であれば、空関数を以下の様に定義すると思います。
(JSの時)

```js:index.js

# 実体のみで、中身の記述はまだの関数
function sayHello() {
}

```

Pythonでは{}で関数は定義しないし、インデントで文末を表現する為、空の関数を定義する為だけの、pass命令が準備されています。

```python

def sayHello2():
    pass
    
print sayHello2() # None
```

pass命令を利用することで、is not definedエラーを回避することができます。

## 変数のスコープ

Pythonでは関数内の変数は関数内でのみ有効な変数となります。

```python
# coding: UTF-8


name = 'Luffy'


def sayHello():
    name = 'Zoro'

# Zoroじゃないよ
print name # Luffy
```

## map

リストの各要素に対して、関数を実行していく命令です。
map命令は以下の様に実行します。

```python
# coding: UTF-8

listItems = [2, 5, 8]


def double(x):
    return x * x

map(double, listItems) # [4, 25, 64]
```

## lambda命令

Pythonでは、たった1回しか使わない様な無名の関数を定義することも可能です。
先ほどの、mapと共に対象の値を2倍するだけのlambdaを定義しています。

```python
# coding: UTF-8

listItems = [2, 5, 8]

result = map(lambda x: x * x, listItems)

print result # [4, 25, 64]
```

lambdaのすぐ後ろには任意の引数を指定します。
(mapはリストの要素を1つずつxに代入します。)
lambdaはreturn文で値のみが返却されるイメージです。

## オブジェクト(クラス・インスタンス)

### クラスの作成

```python
# coding: UTF-8


# 決まり文句として、classの引数にobjectを取る。
class User(object):
    # __init__はJSでいうconstructor
    # 第1引数のselfは必ず初期化時に必要
    def __init__(self, name):
        self.name = name
    # 関数内で対象のクラスのプロパティ・メソッドを利用する際は、
    # 引数に第1引数にはselfを取る。

    def greet(self):
        print 'my name is %s' % self.name

bob = User('Bob')
tom = User('Tom')

print bob.name # 'Bob'
bob.greet() # my name is Bob
tom.greet() # my name is Tom
```

#### ポイント

- classの引数のオブジェクトは決まり文句として、クラス作成の際には指定する。
- `__init__`はクラスがインスタンス化された際の初期化メソッドで、Pythonが準備している。
- 関数を定義する際は必ず、第1引数のself(JSならthis)は必須。
- インスタンス化はnewとかかかない。

### クラスの継承

クラスを継承する際は、classの引数に継承元のクラス名を記載する。

```python
# coding: UTF-8


class User(object):
    def __init__(self, name):
        self.name = name

    def greet(self):
        print 'my name is %s' % self.name


class SuperUser(User):
    def shout(self):
        print '%s is SUPER!' % self.name

luffy = SuperUser('Luffy')
luffy.shout() # Luffy is SUPER!

```

## モジュール

Pythonが予め準備してくれている、便利な命令が詰まったもの。

どんなモジュールがあるかは[公式サイト](https://docs.python.org/)を参考にして下さい。

Pythonが準備しているモジュールは大きく3種類あります。

### 組み込み型モジュール

len, split, joinなどimport文を使わなくても元々準備されているモジュール

### 標準モジュール

Pythonが準備してくれているが、importしないと使えないモジュール

### 外部モジュール

pipで、モジュールをインストールした上で、importして利用するモジュール

以下、外部モジュールをimportする例です。

```python
# coding: UTF-8

import math
import random

# datetimeモジュールの中のdateモジュールのみをimport
from datetime import date

print math.ceil(5.2)  # 6.0

for i in range(5):
    print random.random()

print date.today() # 2016-10-08
```

#### ポイント

datetimeの様な大きなモジュールは、必要部分だけ切り出すことも可能です。
その場合は、from命令を利用します。

# まとめ

Pythonは独特の構文もありますが、基本的に覚えやすくて、可読性もかなり高いと思います。
書いていて気持ちの良い言語だと思います。

次回はPythonで一番人気のフレームワークDjangoを調査したいと思います。