与Ruby相比,Python的限制:lambda

Shy*_*yam 6 ruby python lambda restriction

我正在浏览WikiVS的一些页面,我引用了:

因为Python中的lambdas仅限于表达式,不能包含语句

我想知道这个限制将是一个很好的例子(或更多),最好是与Ruby语言相比较.

感谢您的回答,评论和反馈!

Gle*_*ard 12

我不认为你真的在问lambdas,而是内联函数.

这真的是Python严重烦人的限制之一:你无法定义一个函数(一个真正的函数,而不仅仅是一个表达式)内联; 你必须给它一个名字.这是非常令人沮丧的,因为其他所有现代脚本语言都是这样做的,并且必须将函数移到线外非常痛苦.这也令人沮丧,因为我觉得Python字节码可以代表这一点 - 这只是语言语法不能.

使用Javascript:

responses = {
        "resp1": {
                "start": function() { ...  },
                "stop": function() { ... },
        },
        "resp2": {
                "start": function() { ...  },
                "stop": function() { ... },
        },
        ...
}
responses["resp1"]["start"]();
Run Code Online (Sandbox Code Playgroud)

LUA:

responses = {
        resp1 = {
                start = function() ...  end;
                end = function() ...  end;
        };
        ...
}
responses.resp1.start();
Run Code Online (Sandbox Code Playgroud)

红宝石:

responses = {
    "resp1" => {
        "start" => lambda { },
        "stop" => lambda { },
    },
}
responses["resp1"]["start"].call
Run Code Online (Sandbox Code Playgroud)

蟒蛇:

def resp1_start():
    pass
def resp1_stop():
    pass
responses = {
    "resp1": {
        "start": resp1_start,
        "stop": resp1_stop,
    },
}
responses["resp1"]["start"]()
Run Code Online (Sandbox Code Playgroud)

请注意,JavaScript和Lua没有lambdas:它们没有理由存在,因为内联函数以更加自然和通用的方式覆盖它们.

我可能会认为这是最令人烦恼的日常Python限制.

  • @Glenn,Ruby根本没有函数,它只有方法.Ruby的匿名函数(lambda函数)实际上是函子.并没有什么丑陋或黑客般的关于他们.这只是消息传递OO的结果.Scala做同样的事情,Smalltalk也是如此. (6认同)
  • @Glenn,我并没有说你的评论是恶心的,我指的是Python社区中关于Ruby的一般评论.并不是我没有看到Ruby所做的"丑陋",而是你不了解Ruby.我可以评论Python中强制性"自我"参数的丑陋,但是如果我不理解Python,我只会这样做.他们实现不同的对象模型.它们都是优秀的语言,并且在自己的范例中相当一致. (5认同)
  • @banister:非常丑陋; 一流的功能是任何现代高级语言的基本组成部分.将Ruby与Smalltalk和Scala进行比较肯定无济于事. (3认同)
  • @banister:如果你没有看到Ruby所做的丑陋,那么一定要坚持使用Ruby.我将使用Python,其中函数,方法和仿函数都可以以一致的方式传递,存储和调用.(并且在我的回答中发布*三段评论*时,请不要抱怨广告恶心.) (3认同)
  • 我举了一个Ruby的第二类"内联函数"机制的例子. (2认同)
  • 另外你在Ruby中定义匿名函数的语法非常难看,没有人使用`proc.new {}`,而是使用`lamba {}`或`proc {}`.您的Ruby(1.9)代码应该被重写为:`responses = {"resp1"=> {"start"=> lambda {},"stop"=> lambda {},},}} answers ["resp1"] ["启动"].()` (2认同)
  • +格伦梅纳德没有这么糟糕的设计.这是一个只有你自己的观点,并在这里被揭穿.你只是不愿意听.相反,你愿意尝试使用最糟糕的语法使Ruby看起来更糟糕.停止推动自己的议程,并_fair_使用正确的语法. (2认同)

Mar*_*off 9

关于语句最常遇到的情况可能是Python 2.X的print声明.

例如,

say_hi = lambda name: "Hello " + name
Run Code Online (Sandbox Code Playgroud)

按预期工作.

但这不会编译:

say_hi = lambda name: print "Hello " + name
Run Code Online (Sandbox Code Playgroud)

因为print在Python 2中不是一个合适的函数.

>>> say_hi = lambda name: "Hello " + name
>>> say_hi("Mark")
'Hello Mark'
>>> 
>>> say_hi = lambda name: print "Hello " + name
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

其余的语句print可以在线上的Python文档中找到:

simple_stmt ::=  expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | print_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | global_stmt
                 | exec_stmt
Run Code Online (Sandbox Code Playgroud)

如果你想看到它们失败,你可以在REPL中尝试其余的这些:

>> assert(True)
>>> assert_lambda = lambda: assert(True)
SyntaxError: invalid syntax
>>> pass
>>> pass_lambda = lambda: pass
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

我不确定Python的lambda限制与Ruby proc或者之间有什么相似之处lambda.在Ruby中,所有内容都是一条消息,所以你没有关键字(好吧,你确实有关键字,但是你没有看起来像Python这样的函数的关键字print).在我的头脑中,没有容易错误的Ruby构造将失败proc.