Python初心者メモ

Javaラーな僕がPythonで遊び始めたのでメモ。本当にただのメモ。

# 開発環境
Eclipseで開発環境ができる。Python用の[Pleiades](http://mergedoc.osdn.jp/) All in Oneがあるので落としてくるといい。

## プロジェクト作成
パッケージエクスプローラ 右クリック→「新規」→「プロジェクト」→「Pydevプロジェクト」で作れる。

## Eclipse操作
### パッケージ
Pythonにもパッケージという概念がある様子。
パッケージエクスプローラ 右クリック→「新規」→「Pydevパッケージ」で作れる。

### pyファイル
Pythonのソースファイルはpyという拡張子のファイル
パッケージエクスプローラ 右クリック→「新規」→「Pydevモジュール」で作れる。
クラスやメイン（実行用）のテンプレートを選択できる。

### 実行
メインメソッド（？）のあるpyファイルを 右クリック→「実行」→「Python実行」

# Python構文
## メイン
javaでいう`publoc void main(String... args)`的なやつは下記のように記述する

```py3
if __name__ == '__main__':
    print("I am a beginner")
```
コンソールに`I am a beginner`とでる

EclipseからPydevモジュールの作成で「メイン」のテンプレートを選べば用意される

## インデント
Pythonはインデントでブロックを定義する。

```py3
if __name__ == '__main__':
    print("1")
    if True:
        print("2") # ifの中
        print("3") # ifの中
    else:
        print("4") # elseの中
        print("5") # elseの中
    print("6") # ブロックを抜ける
```

と書くと、1、2、3、6と出力される

## 変数
代入すれば変数宣言と同じこと。

```py3
i = 1
s = "文字列"
b = True
```

## 条件式

### 論理演算子
`and`,`or`,`not`を利用する

### 特殊な判定

#### Noneかどうか
objectを条件式で利用するとNoneのとき「偽」の扱いになる

```py3
o = None
if not o:
    print("oはNoneです")
```

NoneはPythonのnull（みたいなもの）

#### 文字列が空白かどうか
文字列を条件式で利用すると空白のとき「偽」の扱いになる

```py3
s = ""
if not s:
    print("sは空白です")
```
#### 0かどうか
数値を条件式で利用すると0のとき「偽」の扱いになる

```py3
i = 0
if not i:
    print("iは0です")
```

#### 配列が空かどうか
配列（等）を条件式で利用すると空のとき「偽」の扱いになる

```py3
a = []
if not a:
    print("aは空です")
```

## if・ループ

### if
if文はすでに一部書いてしまったけど、下記のように記述する

```py3
if 条件１:
    print("条件１は真")
elif 条件２:
    print("条件１は偽")
    print("条件２は真")
else:
    print("条件１は偽")
    print("条件２は偽")
```
`else if`は`elif`と書く。

### for
for文は下記のように記述する。

```py3
for i in range(10):
    print(i) # 0から9までが順番に出力される

for i in range(3, 7):
    print(i) # 3から6までが順番に出力される

for i in range(1, 12, 2):
    print(i) # 1,3,5,7,9,11が順番に出力される

for s in ["A", "B", "C"]:
    print(s) # AとBとCが順番に出力される
```

Pythonのfor文はJavaの拡張for文のようなもの。
indexによるfor文や、脱出条件や、インクリメント数とかは[range](http://docs.python.jp/3/library/functions.html#func-range)とかを使ってうまいことやる様子。

### while
while文は今までの雰囲気で勘で書けば動く。あまりにも普通なので例は書かない。
なぜかwhile...elseという構文があるが使いどころがわからない。。。

### switch-case
無い様子。

### 三項演算子
三項演算子という名前ではなく、「条件式」・「条件演算子」と説明されている。

http://docs.python.jp/3.5/reference/expressions.html#conditional-expressions

```py3
for i in range(10):
    a = "odd number" if i % 2 else "even number" # 「条件式」というやつ
    print(str(i) + " is an " + a)
```


## 配列・イテレータ
### list
javascriptのノリでインスタンスを生成する

```py3
items1 = []
items2 = ["A", "B"]
```

追加とか削除とか

```py3
items = ["A", "B"]
items.append("C") # JavaのList#add
items.extend(["D", "E", "F"]) # JavaのList#addAll
del items[4] # JavaのList#remove(int)
items.remove("F") # JavaのList#remove(Object)

size = len(items) # JavaのList#size
print("size:" + str(size)) # 4
index2 = items[2] # JavaのList#get
print("index2:" + index2) # C

idx = items.index(index2) # JavaのList#indexOf
print("idx:" + str(idx)) # 2

for item in items:
    print(item) # A,B,C,Dを順番に出力

items2 = items[:] # コピーしたlistインスタンス生成
print(items2) # ['A', 'B', 'C', 'D']（itemsと同じ要素が入ってる）
print(items is items2) # False（別インスタンス）

items.insert(0, "INS") # JavaのList#add(int, Object)
print(items) # ['INS', 'A', 'B', 'C', 'D']
```

`[:]`って？

```py3
items3 = items[1:3] # index 1から2を抽出したlist生成
print(items3) # ['B', 'C']

items4 = items[1:] # index 1から後ろ全部を抽出したlist生成
print(items4) # ['B', 'C', 'D']

items5 = items[:3] # index 3からより前全部を抽出したlist生成
print(items5) # ['A', 'B', 'C']
```

### イテレータ
イテレータというか[「iterable」](http://docs.python.jp/3.5/glossary.html#term-iterable)という概念がある。JavaのIterableクラスと似てる。
「iterable」はPythonの[for文](http://docs.python.jp/3/reference/compound_stmts.html#for)で回せる。
listも「iterable」だし、実はPythonの文字列(str)も「iterable」。
自作もできるようだけど今回は割愛。


### tuple・dict・set
というのもある。

```py3
t = ("A") # tuple
print(type(t))

d = {"A" : 1} # dict
print(type(d))

s = {"A"} # set
print(type(s))
```
詳しいことは調べていない。下記参考
http://www.tohoho-web.com/python/list.html

## 文字列

### 基本

シングルクォートでもダブルクォートでも表現できる。

```py3
s1 = "I am a beginner"
s2 = 'I am a beginner'
```

どっちが一般的かはわからないけど探している感じはダブルクォートかな？


クォート3つなんて技もある。

```py3
s = """パイソンや
ああパイソンや
パイソンや"""

print(s)
```
結果

```
パイソンや
ああパイソンや
パイソンや
```
### 文字列連結
`+`使う。
暗黙キャストはされないので次を利用。

### 文字列へのキャスト
`str`を使う。

```py3
i = 10

print("数値を文字列に" + str(i))
print("文字列と数値を連結" + i) # エラー
```

### 自作クラスの文字列化
`__str__`というメソッドを作成すると文字列化されるときに呼ばれる。
`__str__`がJavaでいうtoStringメソッドの役割の雰囲気（直接は呼べない）。


## メソッド
defと書いて定義する。

```py3
# メソッドはdefで定義する
def method1():
    print("foo")

# 引数は括弧内に書いていく
def method2(arg1, arg2):
    print(arg1)
    print(arg2)

# 返り値はreturnで返す
def method3():
    return "bar"
```

### 引数

#### いろいろな引数の渡し方
こだわらなければ普通に渡せばいいが、（Javaには無い）変わった渡し方もある。

```py3
def method2(arg1, arg2):
    print("---")
    print(arg1)
    print(arg2)

if __name__ == '__main__':
    method2("A", "B") # 普通の
    method2(arg1="A", arg2="B") # こんな渡し方もできる（キーワード引数）
    method2(arg2="B", arg1="A") # この場合順不同でもいいらしい

    method2(*["A", "B"]) # 配列で渡す
    method2(**{"arg2":"B", "arg1":"A"}) # dictで渡す
```
結果は全部一緒

#### デフォルト引数
C++とかにあるやつ。

```py3
# 引数はデフォルト値が定義できる callするとき引数が1つならarg2には"DefaultArg"が入る
def method4(arg1, arg2 = "DefaultArg"):
    print("---")
    print(arg1)
    print(arg2)

if __name__ == '__main__':
    method4("A", "B")
    method4("A") # 2つ目の引数はdefaultを利用
```
結果

```
---
A
B
---
A
DefaultArg
```

dict渡しを前提にすれば第一引数にもデフォルト引数にできそうだがそれは無理っぽい

```py3
def method5(arg1 = "DefaultArg", arg2):
   print(arg1)
   print(arg2)
```
SyntaxErrorになる

#### 可変長引数
tuple型で受け入れるやり方と、dict型で受け入れるやり方がある

##### tuple型の場合

```py3
# *を使うと、tuple型で受け入れる可変長引数
def method_variadic_tuple(arg1, *others): # othersはtuple型の可変長引数
    print("---" )
    print("第一引数:" + arg1)
    print("可変長引数:" + str(others))
    print("可変長引数の長さ:" + str(len(others)))

if __name__ == '__main__':
    method_variadic_tuple("A")
    method_variadic_tuple("A", "B")
    method_variadic_tuple("A", "B", "C")
    method_variadic_tuple("A", *("B", "C")) # 直接tupleで渡すことも可能
    method_variadic_tuple("A", *["B", "C"]) # listもOK
    method_variadic_tuple(*("A", "B", "C")) # 全部tuple渡しも可能
```
結果

```
---
第一引数:A
可変長引数:()
可変長引数の長さ:0
---
第一引数:A
可変長引数:('B',)
可変長引数の長さ:1
---
第一引数:A
可変長引数:('B', 'C')
可変長引数の長さ:2
---
第一引数:A
可変長引数:('B', 'C')
可変長引数の長さ:2
---
第一引数:A
可変長引数:('B', 'C')
可変長引数の長さ:2
---
第一引数:A
可変長引数:('B', 'C')
可変長引数の長さ:2
```

##### dict型の場合

```py3
# **を使うと、dict型で受け入れる可変長引数
def method_variadic_dict(arg1, **others):  # othersはdict型の可変長引数
    print("---" )
    print("第一引数:" + arg1)
    print("可変長引数:" + str(others))
    print("可変長引数の長さ:" + str(len(others)))

if __name__ == '__main__':
    method_variadic_dict("A")
    method_variadic_dict("A", d1="B") # dict可変長引数はこのように渡す
    method_variadic_dict("A", d1="B", d2="C")
    method_variadic_dict(arg1="A", d1="B", d2="C") # dict型を使うなら第一引数も=使った表記のほうがきれい
    method_variadic_dict(d1="B", arg1="A", d2="C") # この場合、第一引数は真ん中でもOK
    method_variadic_dict("A", **{"d1":"B", "d2":"C"}) # 直接dictで渡すことも可能
    method_variadic_dict(**{"arg1":"A" , "d1":"B", "d2":"C"}) # 第一引数もdictにできる。
    # method_variadic_dict(*["A", {"d1":"B", "d2":"C"}]) # 配列渡しはさすがに無理かな？
```
結果

```
---
第一引数:A
可変長引数:{}
可変長引数の長さ:0
---
第一引数:A
可変長引数:{'d1': 'B'}
可変長引数の長さ:1
---
第一引数:A
可変長引数:{'d1': 'B', 'd2': 'C'}
可変長引数の長さ:2
---
第一引数:A
可変長引数:{'d1': 'B', 'd2': 'C'}
可変長引数の長さ:2
---
第一引数:A
可変長引数:{'d1': 'B', 'd2': 'C'}
可変長引数の長さ:2
---
第一引数:A
可変長引数:{'d1': 'B', 'd2': 'C'}
可変長引数の長さ:2
---
第一引数:A
可変長引数:{'d1': 'B', 'd2': 'C'}
可変長引数の長さ:2
```


## クラス
### 定義
`class クラス名(継承元)`という宣言をする。

Eclipseのテンプレートを使えば下記のように書いてくれる。

```py3
class MyClass(object):
    '''
    classdocs
    '''


    def __init__(self, params):
        '''
        Constructor
        '''
```
#### `__init__`
すでにコメント（docstring）があるのでわかるが、コンストラクタは`__init__`と書いて定義する。
引数の`self`は自分のインスタンスで、後ろにコンストラクタで受け入れたいパラメータを書いていく。

### インスタンス生成

```py3
if __name__ == '__main__':
    obj = MyClass("param") # 引数"param"でMyClassを生成してobjに代入
``` 

### インスタンス フィールド変数・メソッド
フィールド変数はインスタンス内部からの場合、`self.フィールド名`で代入すれば変数ができる。
外からの場合は普通に`インスタンスを格納している変数.フィールド名`で代入する。

メソッドはクラスに合わせてインデントして`def`で定義する。
（`__init__`と同じく）第一引数は`self`になる。
外から、呼び出しの際は`self`を抜いた引数を与えて呼び出す。

```py3
class MyClass(object):
    def __init__(self, param):
        self.field1 = "field1" # self.フィールド名に代入すればそれがフィールド変数になる
        print("init param:" + param)

    def foo(self, param): # インスタンスメソッド
        self.field2 = "field2" # フィールド変数はいつでも作れる
        print("foo param:" + param)

if __name__ == '__main__':
    obj = MyClass("A")
    print(obj.field1)
    obj.foo("B")
    print(obj.field2)
    obj.field3 = "field3" # 何なら外からでもフィールド変数を作れる
    print(obj.field3)
```

結果

```
init param:A
field1
foo param:B
field2
field3
```

### スコープ
名前の付け方で表現する。

参考：
http://docs.python.jp/3.5/reference/lexical_analysis.html#reserved-classes-of-identifiers
http://docs.python.jp/3.5/tutorial/classes.html#tut-private

アンダースコアを頭に2つ付ければprivateになる。
（厳密に言えばアクセスする方法はあるのでprivateとは言い切れないかもしれない。）
ただし、`__hoge__`というような後ろにもアンダースコアが2つある名前はPythonのシステム用なので勝手に新しくつけたらダメ。

また、習慣としてアンダースコア1つは非publicとするらしい。

```py3
class MyClass(object):

    def foo(self): # public
        print("foo" )

    def _foo(self): # 習慣としての非public
        print("_foo" )

    def __foo(self): # private
        print("__foo" )

    def call_private_foo(self): # __fooを呼び出すためのメソッド
        self.__foo() # privateのメソッドが呼び出せる

if __name__ == '__main__':
    obj = MyClass()
    obj.foo()
    obj._foo()
    # obj.__foo() # 呼び出し不可
    obj.call_private_foo()
    obj._MyClass__foo() # 厳密に言えばアクセスする方法はある。「_クラス名＋メソッド名」に置き換えられている。ただしEclipseの保管には出てこない
```

結果

```
foo
_foo
__foo
__foo
```


### 継承
`(object)`と書いてある部分を継承したいクラスに変えればとりあえず継承はできる。

多重継承もできるらしいが、初心者の僕は使いこなせる気がしないので今回は割愛。

#### 親クラスのメソッドを呼び出す
ただ継承しただけでは親クラスのコンストラクタは呼ばれない。
下記のように`super(自クラス, self).メソッド名()`と記載して呼び出す。

```py3
class AbsMyClass(object):
    def __init__(self):
        print("AbsMyClass__init__が呼ばれた")


class MyClass(AbsMyClass):
    def __init__(self):
        super(MyClass, self).__init__() # 継承元の__init__を呼び出す
        print("MyClass__init__が呼ばれた")

if __name__ == '__main__':
    obj = MyClass()
```
結果

```
AbsMyClass__init__が呼ばれた
MyClass__init__が呼ばれた
```

何なら親クラスの`__init__`を呼び出さないこともできるし、タイミングも任意だし、何度でも呼べるし自由度がハンパない。
Pythonにまだ慣れない僕は、しょっちゅう書くのを忘れてしょっちゅうハマってる。

## インポート

Eclipseが補完して書いてくれる。
構文については割愛。

---

[Python初心者メモ（その２）](http://qiita.com/ota-meshi/items/e28900e85fa8f25daf30)を書きました。