Python クイックスタート 

久々に使おうとすると、いろいろド忘れしてるので、Bootcamp的なメモ書き。
以下、Ubuntu上で利用例を紹介。
なお、Python2系なのであしからず。

準備
-----

まずPythonの各種ライブラリをインストールするためのツールを準備する。

```:easy_install
$ sudo apt-get install python-setuptools
```

```:pip
$ sudo apt-get install python-pip
```

ライブラリが必要になったら、pipコマンドで追加する。(例: feedparser)

```:(例)
$ sudo pip install feedparser
```

プロキシ経由の場合。

```:(例)
$ sudo pip install feedparser --proxy proxy.yourdomain.xx:8080
```

実行
------

スクリプトを記述したファイル(例: my_python.py)の実行。

```bash
$ python my_python.py
```

コーディング スタイル
------

プロジェクトとかで共通のルールを作ればよいが、PEP8に準拠するのが近道。

* [Python のコーディング規約 PEP8 に準拠する](http://qiita.com/ynakayama/items/8616f4c0c6e372de9a42)
* [PEP8 (日本語訳)](http://pep8-ja.readthedocs.org/ja/latest/)

あと、Google Python Style Guideなるものもある。

* [本家 (英語)](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html)
* [日本語訳](http://works.surgo.jp/translation/pyguide.html)

ぱっと使い方を思い出したい場合は、このページの内容でなんとかなるが、本格的にプログラム業務を始める場合などは、上記の規約を一読しておくのがよい。
(記法もそうだが、いろんなテクニックが参考になる)

以下、ごく要点だけ。

### インデント

スペース4文字で。(タブは使わない)

### 空白

丸括弧(parentheses)、角括弧(square bracket)、波括弧内には空白を入れない。

```py
# Yes:
spam(ham[1], {eggs: 2}, [])
```

```py
# No:
spam( ham[ 1 ], { eggs: 2 }, [ ] ) 
```

コンマ、セミコロン、コロンの前には空白を入れない。行末以外のコンマ、セミコロン、コロンの後には空白を入れる。

```py
# Yes:
if x == 4:
    print x, y
x, y = y, x
```

```py
# No:
if x == 4 :
    print x , y
x , y = y , x
```

引数、配列、スライスの開始である丸括弧(parentheses)、角括弧(square bracket) を開く前には空白を入れない。

```py
# Yes:
spam(1)
dict['key'] = list[index]
```

```py
# No:
spam (1)
dict ['key'] = list [index]
```

代入 (=)、 比較 (==, <, >, !=, <>, <=, >=, in, not in, is, is not)、 評価 (and, or, not) などの項演算子の両側には空白を入れる。 算術演算子の両側の空白は個人判断であるが、項演算子の両側には空白文字を入れる。

```py
# Yes:
x == 1
```

```py
# No:
x<1
```

キーワードの値や初期値のための ‘=‘ 記号の両側には空白を入れない。

```py
# Yes:
def complex(real, imag=0.0): return magic(r=real, i=imag)
```

```py
# No:
def complex(real, imag = 0.0): return magic(r = real, i = imag)
```

メンテナンス性の低下につながるため、連続する行を垂直にそろえるために空白は入れない。(:, #, =, 等):

```py
# Yes:
foo = 1000  # comment
long_name = 2  # comment that should not be aligned

dictionary = {
    "foo": 1,
    "long_name": 2,
    }
```

```py
# No:
foo       = 1000  # comment
long_name = 2     # comment that should not be aligned

dictionary = {
    "foo"      : 1,
    "long_name": 2,
```    

### ネーミング

| タイプ| 内部 | 外部 |
|:-----------|:------------|:------------|
| パッケージ | lower_with_under | |
| モジュール | lower_with_under | _lower_with_under |
| クラス | CapWords | _CapWords |
| 例外 | CapWords |  |
| 関数 | lower_with_under() | _lower_with_under() |
| グローバル / クラス定数 | CAPS_WITH_UNDER | _CAPS_WITH_UNDER |
| グローバル / クラス変数 | lower_with_under | _lower_with_under |
| インスタンス変数 | lower_with_under | _lower_with_under (protected) or __lower_with_under (private) |
| メソッド名 | lower_with_under() | _lower_with_under() (protected) or __lower_with_under() (private) |
| 関数 / メソッドパラメータ | lower_with_under |  |
| ローカル変数 | lower_with_under |  |

コーディング
------

### Hello World

```python
print 'Hello World'
```

### コードブロックの扱い

Pythonの超基本。
`{}` ではなく、インデントでブロック化する。

```c:C言語などのスタイル
if (cond) {
    ...
}
else {
    ...
}
```

```python:Pythonのスタイル
if cond:
    ...
else:
    ...
```

### print文のフォーマット

`%d` や `%s` を使ったフォーマット出力が可能。

```python
ans = 100
print 'answer is %d' % ans
```

変数を複数扱う場合は `()` で囲う

```python
count = 1
line = 'hogehoge'
print '%d: %s' % (count, line)
```

### print文の改行の扱い

print文は末尾に `\n` を付けなくても、自動で改行される

```python
print 'My name is '
print 'John' # 改行されて出力
```

改行させないためには、文字リテラルの末尾に `,` をつける。リテラル内でなく外に付けること。

```python
print 'My name is ',  # , をつける
print 'John' # My name is John.
```

### コメント文

`#` 以降がコメント文となる

```py
# comment!

var = 10 # initial value
```

複数行にまたがるコメントアウト記法はない。
文字列の記法`'''`を使うことで代替可能。
(こうした記述はコンパイル時に無効化される)

```py
'''
xxxx
'''
class MyClass:
    pass
```

### 途中改行

Javaなどと異なり、行末の `;` が不要。
その代わり、行中で気軽に改行できない。

```py:NG
# NG
msg = 'I am not in Japan now.'
    + 'But I have been there.'
```

行末に `\` を付けることで途中でも改行できる。

```py:OK
# OK
msg = 'I am not in Japan now.' \
    + 'But I have been there.'
```

`()` や `[]` でencloseされた文中は途中改行できる。
また、改行後のインデントも自由でよい。

```py:OK
my_method('My', 'Name',
    'Is', 'Mike', 'Davis', '.')

def func():
    v = [1, 2, 3,
4, 5, 6] # 文法的にはOK, 見にくいので避ける。
```

### 変数

変数宣言で型の指定は不要。
数値や文字列、配列もすべてオブジェクト。

```py
val = 10
msg = 'foo'
ary = [1, 2, 3]
c = MyClass()
```

### 配列定義

他の言語でもよく見る形。
なお、要素間で改行を入れてもよい。

```py
list = [
     "Ichiro",
     "Jiro",
     "Saburo"]
```

### 論理演算

`|` とか `&` は使えない。
代わりに `and` と `or` を使う。

```python
if a == 1 and b == 2:
    # do something
```

### Boolean の扱い

`True`, `False` を使う。

```py
if True:
    print "Always True"
``` 

### null の扱い

`null` ではなく `None` を使う。

```python
if value is None:
    # do something
```

### ３項演算子

Javaなんかと記法が違うので注意。

```python
data = 100
value = 'even' if data % == 0 else 'odd'
```

### 関数定義

`def` を使う。
なお、pythonでは関数もオブジェクト。

```py
def func(value):
     return value*2
```

### main処理の書き方

以下のように書くと、main処理が分かりやすくなる。

```python
def main():
    # do something
    ...

if __name__ == "__main__":
    main()
```

### 実行時パラメータを扱う

sysモジュールを使う。
`argvs[0]` はスクリプト名になる。

```python
import sys

argvs = sys.argv
argc = len(argvs)
if (argc != 2):
     print 'Usage: %s <file>' % argvs[0]
     quit()

print 'param: %s' % argvs[1]
```

### is と == 

`is` は同一性 (Javaでいう ==)
`==` は同等性 (Javaでいうequals())
またJavaとは違い数値はすべてオブジェクト。

その数値の場合、ちょっと理解がややこしい。

```py
a = 1
b = 1
if a is b:
    print "a is b"
if a == b:
    print "a == b"
```

直感的に、"a == b" ではあっても、"a is b" ではないはずだが、
上記を実行すると、"a is b" も出力される。

```
"a is b"
"a == b"
```

これは、不変データの再利用やらキャッシュが効いているためらしい。
ちなみに、コンパイラが賢いためか、以下の場合も、"a is b" になる。 (当然 a == b)

```py
a = 1 + 3
b = 2 + 2
if a is b:
    print "a is b"
```

文字列の場合は、数値と同様に再利用されると `is` でTrueが返る。
ただし、動的に生成される場合には `is` がFalseになるケースもあるので注意する。

```py
x = "X"

a = "XY"
b = x + "Y"

if a == b:
    print "a == b"
if a is b:
    print "a is b"
```

```:output
a == b
```

ちなみに、`id()` 関数を使うと、オブジェクトのアドレスが得られる。
`is` が想定と違う動作になる場合に、デバッグ用途で使うとよい。

```py
a = "foo"
print "a at 0x%x" % id(a)
```

### if-else 構文

これもよく忘れるが、`elif` を使う。

```py
if i % 15 == 0:
    print 'FizzBuzz'
elif i % 3 == 0:
    print 'Fizz'
elif i % 5 == 0:
    print 'Buzz'
else:
    print i
```

### for / while 文

`range()` を使うと便利。
`range()`の第二引数は最大値となるが、この値は**含まない**。

```py
for i in range(0, 5):
    print 'id = %d' % i
```

```:output
id = 0
id = 1
id = 2
id = 3
id = 4
```

途中から開始する場合。

```py
for i in range(2, 3):
    print 'id = %d' % i
```

```:output
id = 2
```

第三引数でstepを指定できる。
この場合も第二引数の最大値は超えない。

```py
for i in range(0, 10, 2):
    print 'id = %d' % i
```

```:output
id = 0
id = 2
id = 4
id = 6
id = 8
```

配列も指定できる。

```py
for i in [0, 2, 3]:
    print 'id = %d' % i
```

```py
for c in ['red', 'green', 'blue']:
    print 'color = %s' % c
```

部分配列も指定できる。

```py
colors = ['red', 'green', 'blue']
for c in colors[1:]:
    print 'color = %s' % c
```

```:output
color = green
color = blue
```

for-elseという構文がある。
forのループ処理が完了した場合にelse句が実行される。

```py
for i in range(0, 3):
    print 'i = %d' % i
else:
    print 'done'
```

```:output
i = 0
i = 1
i = 2
done
```

途中でbreakするとelse句は実行されない。

```py
for i in range(0, 3):
    print 'i = %d' % i
    if i == 1:
        break
else:
    print 'done' # 実行されない
```

while文。
こちらもelse句が使える。

```py
i = 5
while 0 < i:
    print 'id = %d' % i
    i -= 1
else:
    print 'done'
```

### 改行を含む文字リテラル (ヒアドキュメント風)

`'''` で囲う。

```python
val = '''this is a pen.
but it's not my favorite color.
I love red.
'''
```

コード上でインデントして記述したい場合は、以下のような記述方法がある。

```python
import textwrap

print textwrap.dedent('''\
    あいうえお
    かきくけこ
    さしすせそ''')
```
### try-except 構文

Javaのtry-catch-finally構文と同じように、try-except-finally構文で例外を処理できる。
また、Pythonではelse句の指定が可能で、try内で例外の発生がなく処理が完了した場合に実行される。

```py
try:
    val = int("123") # no exception
    print 'val = %d' % val
except ValueError:
    raise
else:
    print '>> else'
finally:
    print '>> finally'
```

この場合、try句でError/Exceptionは発生しないので、以下のように出力される。

```:output
val = 123
>> else
>> finally
```

あえてtry句でErrorを発生させる。

```py
try:
    val = int("abc") # ValueError
    print 'val = %d' % val
except ValueError:
    # raise
    pass
else:
    print '>> else'
finally:
    print '>> finally'
```

この場合、出力は以下のようになる。

```:output
>> finally
```

また、補足するErrorやExceptionは `()` でまとめて指定できる。

```py
try:
   ...
except (XXXError, YYYError, ZZZException):
   ...
```

### 簡単なクラスの定義

以下のように定義できる。
メンバー変数は、いちいち宣言する必要はない。
第一引数 `self` が必ず必要で、呼び出すときには指定は不要。

```python
class ClassName:
    def __init__(self, arg1, arg2):
        self.member1 = arg1
        self.member2 = arg2

    def method(self, param1):
        // logic  
```

インスタンス化 -> 呼び出し。

```python
data = ClassName('nameA', 'nameB')
data.method('param1')
```

### 文字列に変換

以下の例だとprintができない。

```python
val = 120
print "val + " val
```

`str()` で明示的に文字列に変換するとできる。

```py
printt "hoge=" + str(123)
```

### 整数に変換

文字列を整数に変換。

```py
val = int("23")
```

変換できない場合は`ValueError`が発生。

```py
try:
    v = int("abc")
except ValueError:
    print 'ValueError occurs'
```

### Hex文字列を10進数intに変換

int()の第二引数を指定する

```py
value10 = int ('0xF6', 16)
```

### システムコマンド実行

可搬性のため、できれは使わないように。

```py
import os
os.system('<command>')
```

```py:(例)
os.system('grep TvC -R .')
```

### システムコマンドの結果を受け取る

システムコマンドの結果を文字列として受け取れる。
結果がないときは、Noneではなく空文字が返るっぽい。

こちらも可搬性のため、多用はしない。

```py
import commands
r = commands.getoutput('<command>')
```

```py:(例)
r = commands.getoutput('date')
```

サポートされない記法
------

### switch文

if - elif を使えばよい、とのこと。

### インクリメント演算子

数値型もオブジェクト(不変)であることもあり、`i++` や `--i` とは書けない。
`i += 1` などを使う。