これめんどくさくない?
いきなりですが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ってないよね?)