JavaユーザーがPythonを使って印象的だった点

# はじめに
最近Pythonを用いてLambdaを開発する機会がありました。今までJavaを中心に開発してきた自分にとっては新鮮な経験で、Javaと違ってPythonだとこのように書く・書けるのかと感じたところがありました。

今回はJavaを中心に使用している開発者目線でPythonに触れて印象的だった点を書いてみようと思います。

ちなみにPythonのバージョンは3.8です。

## クラスとメソッド、アクセス制限
オブジェクト指向に慣れるとクラスにデータとメソッドをカプセル化したくなります。

例えばJavaの場合だと

```Java:PersonName.java

public class PersonName {
  private String firstName;
  private String lastName;

  public PersonName(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public fullName() {
    return firstName + " " + lastName;
  } 
}
```

といった具合になりますが、Pythonだと

```Python:person_name.py
class PersonName:
  def __init__(self, first_name, last_name):
    self.first_name = first_name
    self.last_name = last_name

  def full_name(self):
    return self.first_name + " " + self.last_name
```

と書けば実現できてしまいます。

印象的だったのは第一引数に`self`が入ることと、コンストラクタに設定してしまえば、Javaのようにいちいちクラス変数を書かなくても定義できてしまうことです。

また、上記の例には書いていませんが、クラス内で定義されたメソッドをクラス内で使用する場合に`self.メソッド名`と`self`を書く必要があるのも印象的でした。

ただしPythonにはJavaのように`public`や`private`といったアクセス修飾子は存在せず、アクセスを制限したい場合には`_`や`__`を変数・定数やメソッドの頭につけて管理しているようです。

開発チームのメンバーを信頼する性善説的な仕様・慣習だなと感じられて印象的な点でした。

## listの空チェック

Javaだと例えば[CollectionUtils](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html)を使って以下のように書くかと思います。

``` Java:EmptyCheck.java
List<String> sampleList = new ArrayList<>();
if (CollectionUtils.isEmpty(sampleList)) {
  // 何らかの処理
}
```

これがPythonだと

``` Python:EmptyCheck.py
sample_list = []
if not sample_list:
  # 何らかの処理
```
と書くことができます。

`if 変数:`で変数の中身が存在する場合の分岐が書けること、`if not 条件:`で条件の否定が取れることの合わせ技ですが、サクッと書くことができて非常に便利だと思いました。

## deepcopy
プログラミングにおいて変数の値をコピーする場合、単に`=`を用いてしまうとコードの内容によっては破壊的変更・代入が生じてしまう可能性があります。こうした事故を防ぐためにJavaでコピーをする場合cloneメソッドを実装したりするのですが、面倒だったりします。

Pythonの場合だと`copy`をインポートして、

```Python:deepcopy.py
import copy
sample_list = [1, 2, 3]
copied_list = copy.deepcopy(sample_list)
```

といった具合に書けばコピーができてしまい、こちらも便利だなと思いました。

## 平坦化(flatten)
データベースから1カラムを取得した場合、下記のようなデータが取得されるため、これを平坦化したいと思いました。

```Python:fetch_result.py
result = ((1,), (2,), (3,))
```

これを平坦化するには`sum`を利用します。

```Python:flatten.py
result = ((1,), (2,), (3,))
flatten_result = sum(result, ())
print(flatten_result) #(1, 2, 3)
```

`sum`は第二引数の値に`+`を演算していくので、上記の例の場合`result`の中身が順番に処理されて、平坦化することができます。
いわゆるflattenを行うのに`sum`を使用して実現できるのが興味深かったです。

## リスト内包表記
Pythonにてリストを作成する時にリスト内包表記を使用すると下記のようにリストを作成することができます。

```Python:list_comprehensions.py
sample_list = [num for num in range(1, 100)]
```

わかってしまえばなんてことないのですが、参考にしていた既存の実装で最初にリスト内包表記に出会った際に、上記の例の場合

```Python:list_comprehensions.py
sample_list = [
  num
  for num in range(1, 100)
]
```
と書かれていたので、何となくやりたいことはわかったものの「for文が下にある？」と非常に違和感を抱いたという思い出込みで印象的な機能でした。

# おわりに
普段使っている言語とは別の言語で開発するという経験は新鮮でしたし、それぞれの言語の良いところが見えてくるので、良い経験だなぁと改めて思いました。

自分が調べていないだけかもしれないですが、「XXを普段使っている人がYYを使った感想」といった記事がもっとあるとお互いの言語のことがわかって面白いので色々な人に気軽に書いて欲しいなと思うようになりました。

ぜひ皆さんも普段使っていない言語を使ったときの感想・体験談を書いてみてください。

最後までお読みいただきありがとうございました。

# 参考

https://www.sbcr.jp/product/4797389463/

https://docs.python.org/ja/3.8/library/copy.html

https://docs.python.org/ja/3.8/library/functions.html#sum

https://docs.python.org/ja/3.8/tutorial/datastructures.html#list-comprehensions

https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html