IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

Python の lambda の中で手続き的な書き方をする

PythonJavaScript は似てる

でも、 lambda の中に手続き的な書き方ができない

Python の lambda

lambda 引数: 式

で、式の部分にはブロックも書けない。
これでは、 JavaScript 脳の人はコードを書けないではないか!!!

というわけで

lambda の中で手続きを書く方法を考えてみた

逐次処理
(lambda: (
  式,
  式,
)[-1])
条件分岐
(lambda: (
  式,
  (lambda: (
    式,
    式,
    式,
  )[-1]) if (条件) else (lambda: (
    式,
    式,
    式,
  )[-1]),
  式,
)[-1])
繰り返しは。。。。

まあ、再帰で書くとしておこう

でも><

Python の代入 = は文だった><
なので、 lambda の中で文を書けない。困った。
で、以下のような感じにしてみた

// print も文なので
def p(m): print(m)

(lambda: (
  locals().__setitem__('a', 1), // a = 1,
  p(a),
)[-1])

これはできなかった><
id:nishiohirokazu 曰く locals() が返す値はコピーなのだそうだ

という訳で変数の仕組みは自分で作ることにする

スコープチェーンのクラスを作る
# id:nishiohirokazu に添削されました><
# 直したあとのです><
class Scope(object):
    def __init__(self, parent = None):
        self.parent = parent
        self.hash = {}

    def var(self, key, value = None):
        self.hash[key] = value
        return value

    def set(self, key, value):
        if key in self.hash or not(self.parent):
            self.hash[key] = value
        else:
            self.parent.set(key, value)
        return value

    def get(self, key):
        if key in self.hash or not(self.parent):
            return self.hash[key]
        else:
            return self.parent.get(key)
        
    def __setattribute__(self, key, value):
        return self.set(key, value)

    def __getattr__(self, key):
        return self.get(key)
使う
_ = Scope()

_.var('hoge', 1) # var hoge = 1

_.f = lambda: ((lambda _: (

    _.var('hoge', 2), # var hoge = 2

    p(_.hoge), # p(hoge)

)[-1])(Scope(_)));

_.f()

p(_.hoge) # p(hoge)

_.hoge = 3

p(_.hoge)

わーできたよ!

これで JavaScriptfunction(){} みたいなのができるよ!やった!

突っ込まれた><

http://d.hatena.ne.jp/nishiohirokazu/20080304/1204634146
ありがとうございました!直しました!