IT戦記 このページをアンテナに追加 RSSフィード Twitter

2008-03-04

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(){} みたいなのができるよ!やった!

突っ込まれた><

Re: Python の lambda の中で手続き的な書き方をする - 西尾泰和のはてなダイアリー

ありがとうございました!直しました!

taka.BRKtaka.BRK 2008/03/05 10:59 Mozillaのビアード氏の微妙な表情に笑った(^_^;)。
http://www.itmedia.co.jp/enterprise/articles/0803/05/news012_2.html

akitsakits 2010/02/15 02:21 def bind(x, f): return f(x) で
x1 = 式1; x2 = 式2; ... ; 式n を
bind (式1, lambda(x1): bind (式2, lambda(x2): ..:式n)..))
もありますね

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。