我正在寻找允许在 python 中内联定义函数或多行 lambda 的最佳配方。
例如,我想做以下事情:
def callfunc(func):
func("Hello")
>>> callfunc(define('x', '''
... print x, "World!"
... '''))
Hello World!
我在这个答案define
中找到了一个函数示例:
def define(arglist, body):
g = {}
exec("def anonfunc({0}):\n{1}".format(
arglist,
"\n".join(" {0}".format(line) for line in body.splitlines())), g)
return g["anonfunc"]
这是一种可能的解决方案,但并不理想。理想的功能是:
- 对缩进更聪明,
- 更好地隐藏内脏(例如,不在
anonfunc
函数的范围内) - 提供对周围范围/捕获中的变量的访问
- 更好的错误处理
还有一些我没有想到的事情。一旦完成了上述大部分工作,我就有一个非常好的实现,但不幸的是我输了。我想知道是否有人做过类似的东西。
免责声明:
我很清楚这在 Python 用户中是有争议的,被认为是 hack 或 unpythonic。我也知道 python-dev 邮件列表上关于多行 lambda 的讨论,并且故意省略了类似的功能。然而,从同样的讨论中,我了解到许多其他人也对这种功能感兴趣。
我不是在问这是否是一个好主意,而是:鉴于一个人已经决定实施这个,(出于乐趣和好奇,疯狂,真的认为这是一个好主意,或者被枪指着)如何使匿名define
工作尽可能接近def
使用 python(2.7 或 3.x)当前的设施?
例子:
关于为什么,这对于 GUI 中的回调非常方便:
# gtk example:
self.ntimes = 0
button.connect('clicked', define('*a', '''
self.ntimes += 1
label.set_text("Button has been clicked %d times" % self.ntimes)
''')
与定义函数相比的好处def
是您的代码具有更合乎逻辑的顺序。这是取自 Twisted 应用程序的简化代码:
# twisted example:
def sayHello(self):
d = self.callRemote(HelloCommand)
def handle_response(response):
# do something, this happens after (x)!
pass
d.addCallback(handle_response) # (x)
注意它看起来是多么的不正常。我通常会分解这样的东西,以保持代码顺序 == 执行顺序:
def sayHello_d(self):
d = self.callRemote(HelloCommand)
d.addCallback(self._sayHello_2)
return d
def _sayHello_2(self, response):
# handle response
pass
这更好。排序但更详细。现在,使用匿名函数技巧:
d = self.callRemote(HelloCommand)
d.addCallback(define('response', '''
print "callback"
print "got response from", response["name"]
'''))