概要
某OSSで見つけたテクニック。
bs = BookShelf('XX入門', '初めてのYY', '今さら聞けないZZ')
bs.map_(lambda: print(this))
stdout
XX入門
初めてのYY
今さら聞けないZZ
唐突に出現したthis
。一体どこから生えてきたのか?
種明かし
コールバック呼び出し前に細工をしていた。
class Book:
def __init__(self, name):
self._name = name
def __str__(self):
return self._name
class BookShelf:
def __init__(self, *book_names):
self._books = [*map(Book, book_names)]
def map_(self, callback):
for book in self._books:
callback.__globals__['this'] = book
callback()
del callback.__globals__['this']
分かってみれば大したこと無いが、
インタプリタやIDEの拡張を疑いしばらく悩みこんでしまった。
バッドプラクティスだと思う理由
次のように、引数として渡した方がPythonicだと思うから。
class BookShelf:
def __init__(self, *book_names):
self._books = [*map(Book, book_names)]
def map_(self, callback):
for book in self._books:
callback(book)
bs = BookShelf('XX入門', '初めてのYY', '今さら聞けないZZ')
bs.map_(lambda this: print(this))
Zen of Python を大事にしたい。
Explicit is better than implicit.
暗示するより明示するほうがいい。