LoginSignup
0
1

More than 3 years have passed since last update.

Pythonで任意のクラスにmapとto_listを実装する(プライベート用)

Last updated at Posted at 2021-01-24

これめんどくさくない?

いきなりですがPythonの仕様上こう書くのってめんどくさくないですか?

list(map(lambda x: x + 1, [0, 1, 2])) # => [1, 2, 3]

あとから,listで括りなおすのとかmapの引数が先に関数なのとか,わりとややこしいように思います。

つまり他の言語みたいに,下のように書きたい!

[0, 1, 2].map(lambda x: x + 1).to_list() # => [1, 2, 3]

これをやるためのいい方法を見つけてしまったので記事にします(きちんとした開発には不向きな方法なので,個人的な範囲での利用をオススメします)。

classにメソッドを追加できないの?

Pythonではclassにメソッドを追加するための方法として、次のような方法があります、

# クラスを定義しインスタンスを生成
class Bomb:
    pass
my_bomb = Bomb()

# 追加したいメソッドを関数として定義しクラスのプロパティに追加
def explosion(self):
    print("大爆発!")

Bomb.explosion = explosion

# 追加したメソッドが生成済みのオブジェクトからも利用できる
my_bomb.explosion()  # => 大爆発!

この方法は自分で定義したclassであればうまくいきますが。list, object等の組み込みclassではうまく行きません。

object.to_list = lambda self: list(self)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-9c86e5ed31fa> in <module>()
----> 1 object.to_list = lambda self: list(self)

TypeError: can't set attributes of built-in/extension type 'object'

forbiddenfruitを使う

そこでforbiddenfruitを使います。名前の通り、禁断の果実なので、あまり多用しないように笑

pip install forbiddenfruit

としたのち、

from forbiddenfruit import curse

def to_list(self):
    return list(self)

curse(object, 'to_list', to_list)

とすることで、任意のobjectにto_listメソッドが実装されます。
同様に

curse(object, 'map', lambda self, f: map(f, self))

とすることで、mapメソッドが実装されます。

すると、

[0, 1, 2].map(lambda x: x + 1).to_list() # => [1, 2, 3]

となり成功です。ただし、もとからto_listやmapなどが実装されている場合、どうなるかわかりませんので、objectではなく、もっと限られたクラスで実装すべきだとはおもいます(iterableのbase classってないよね?)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1