pythonを触ってみた感想

# 概要
【内容】
pythonを触ってみて感じたJavaとの違いや気になった点をまとめています。
※途中でコードスタイルのチェックを入れたので、ソースのスペースの入れ方などが前半と後半で違います。
【想定読者】
pythonは未経験だが、Javaでのコーディング経験がある方を対象にしています。
【環境】
プラットフォームはAnaconda、IDEはSpyderを使用しています。

# 目次
[1.インデントを正しく書かないとコンパイルエラーが発生](#1-インデントを正しく書かないとコンパイルエラーが発生)
[2.for文での添え字の取得](#2-for文での添え字の取得)
[3.switch文がない](#3-switch文がない)
[4.型の宣言が不要](#4-型の宣言が不要)
[5.関数にデフォルト引数を設定できる](#5-関数にデフォルト引数を設定できる)
[6.インスタンスメソッドを呼び出す際は暗黙的に引数が1つ渡される](#6-インスタンスメソッドを呼び出す際は暗黙的に引数が1つ渡される)
[7.pythonにはオーバーロードがない](#7-pythonにはオーバーロードがない)

# 1. インデントを正しく書かないとコンパイルエラーが発生
下記のようにif文やfor文の中で行う処理にインデントをつけないと、コンパイルエラーが発生します。

```python:test1.py
words =['a','b']
for w in words:
# コンパイルエラーになる
print(w)

old = 15
if old == 15:
# コンパイルエラーになる
print('a')
```
" "（スペース）や"    "（タブ）でインデントをつけるとコンパイルが通る。

```python:test2.py
words =['a','b']
for w in words:
# 正常に通る
 print(w)

for w in words:
# 正常に通る
    print(w)
```

# 2. for文での添え字の取得
pythonのfor文はJavaでいう拡張for文と同じため、添え字を取得したいときはenumerateを使用する必要があります。

```python:test3.py
words =['a','b']
for w in (enumerate(words)):
    #実行結果は(0, 'a')(1, 'b')
    print(w,end='')
```
# 3. switch文がない
pythonにはcやJavaにあるswitch文がありません
そのため、if文もしくは辞書（Javaでいうmapのようなもの）を使用してコーディングする必要があります。

```python:test4.py
# print1を出力する関数
def printer1():
    print("print1")

# print2を出力する関数    
def printer2():
    print("print2")

# 関数の辞書
dictionaly ={'1':printer1,
             '2':printer2
             }

# 辞書から関数を取得
func = dictionaly['1']
#取得した関数の呼び出し "print1"が出力される
func()
```
# 4. 型の宣言が不要
pythonはJavaScript等と同じインタープリンタ型の言語のため、変数の型の宣言が不要です。
※Javaにもローカル型推論というvarで型を意識せずに変数を宣言する方法がありますが、pythonはvarの記載も不要です。
ローカル型推論の詳細は下記を参照。
[ローカル変数の型推論](https://qiita.com/RinTenma/items/80300ce91d2ea714d766)

```python:test5.py
# 数値
num = 10

# 文字列
char = '文字'

# 関数の宣言
def function():
    print("function")

# 関数の代入    
func = function
# 関数の使用　"function"と出力される
func()

# ちなみにこっちは実行時にエラーになる
func2 = function()
#上の記載だと関数の戻り値がfunc2に設定されるため
func2()
```
# 5. 関数にデフォルト引数を設定できる
関数を定義するときに引数にデフォルト値を設定することができます。※最後の引数のみ。
調べてみたところ、javaでも下記のサイトにまとめられているように疑似的にデフォルト引数を作成する方法がありました。
[Javaでデフォルト引数を実装する方法まとめ](https://qiita.com/nimzo6689/items/c70cba05211393674b60)

```python:test6.py
# パラメータを出力する関数（デフォルト値は"デフォルト"）
def printer1(msg="デフォルト"):
    print(msg)


# パラメータと出力
printer1("パラメータ")

# デフォルトと出力
printer1()
```

# 6. インスタンスメソッドを呼び出す際は暗黙的に引数が1つ渡される
インスタンスメソッドを呼び出す場合は、該当のクラスのインスタンスが引数として暗黙的にメソッドに渡されます。そのため、メソッド側にインスタンスを受け取るための引数を設定する必要があります。
※下記のソースのprintet1からselfを削除すると実行時に引数が多いとエラーになります。

```python:test7.py
class Testclass:
    name = "高木"

    # 高木+パラメータを出力するメソッド
    def printer1(self, msg="渉"):
        print(Testclass.name + msg)


testclass = Testclass()
# 高木進と出力
testclass.printer1("進")

# 高木渉と出力
testclass.printer1()
```

# 7. pythonにはオーバーロードがない
pythonにはオーバーロードの仕組みがありません。
但し、下記のようにsingledispatch※を使用して、疑似的なオーバーロードを作成することはできます。
※デコレータ。デコレータについては長くなるので割愛。
因みに、下記のソースを見て頂ければ気が付くと思いますが、pythonは引数の名称、型の順で記載します。

```python:test8.py
from functools import singledispatch

CAKE = "ケーキ"


# パラメータ+定数を出力する関数
@singledispatch
def printer1(material: str):
    print(material + CAKE)


# 定数+パラメータ+"個"を出力する関数
@printer1.register
def _(num: int):
    print(CAKE + str(num) + "個")


# チョコレートケーキと出力
printer1("チョコレート")

# ケーキ10個と出力
printer1(10)

```