Ruby在Python中的轻拍成语

Mic*_*ski 11 ruby python idioms

有一个有用的Ruby习惯用法tap允许你创建一个对象,对它做一些操作并返回它(我在这里只使用一个列表作为例子,我真正的代码更多参与):

def foo
  [].tap do |a|
    b = 1 + 2
    # ... and some more processing, maybe some logging, etc.
    a << b
  end
end

>> foo
=> [1]
Run Code Online (Sandbox Code Playgroud)

使用Rails有一个类似的方法returning,所以你可以写:

def foo
  returning([]) do |a|
    b = 1 + 2
    # ... and some more processing, maybe some logging, etc.
    a << b
  end
end
Run Code Online (Sandbox Code Playgroud)

这说明了一切.无论你对对象做了多少处理,它仍然清楚它是函数的返回值.

在Python中我必须写:

def foo():
  a = []
  b = 1 + 2
  # ... and some more processing, maybe some logging, etc.
  a.append(b)
  return a
Run Code Online (Sandbox Code Playgroud)

我想知道是否有办法将这个Ruby成语移植到Python中.我的第一个想法是使用with语句,但return with语法无效.

Muh*_*uri 24

简短回答:Ruby鼓励方法链,而Python则不然.

我想正确的问题是:Ruby tap对什么有用?

现在我对Ruby知之甚少,但通过谷歌搜索,我得到的印象tap是概念上有用的方法链接.

在Ruby中,风格:SomeObject.doThis().doThat().andAnotherThing()非常惯用.例如,它是流畅接口的概念的基础.Ruby tap是一个特殊情况,而不是SomeObject.doThis()你动态定义doThis.

为什么我要解释这一切?因为它告诉我们为什么tap在Python中没有很好的支持.有了适当的警告,Python不会进行调用链接.

例如,Python列表方法通常返回None而不是返回变异列表.函数喜欢mapfilter不是列表方法.另一方面,许多Ruby数组方法确实返回修改后的数组.

除了某些ORM之外的某些情况,Python代码不使用流畅的接口.

最后,它是惯用的Ruby和惯用的Python之间的区别.如果您要从一种语言转到另一种语言,则需要进行调整.


Mar*_*ers 7

您可以在Python中实现它,如下所示:

def tap(x, f):
    f(x)
    return x
Run Code Online (Sandbox Code Playgroud)

用法:

>>> tap([], lambda x: x.append(1))
[1]
Run Code Online (Sandbox Code Playgroud)

然而,它在Python 2.x中的使用并不像在Ruby中那么多,因为Python中的lambda函数是非常严格的.例如,您无法内联调用print,因为它是一个关键字,因此您无法将其用于内联调试代码.您可以在Python 3.x中执行此操作,尽管它不像Ruby语法那样干净.

>>> tap(2, lambda x: print(x)) + 3
2
5
Run Code Online (Sandbox Code Playgroud)


aar*_*ing 7

如果你想要这么糟糕,你可以创建一个上下文管理器

class Tap(object):
    def __enter__(self, obj):
        return obj

    def __exit__(*args):
        pass
Run Code Online (Sandbox Code Playgroud)

您可以使用如下:

def foo():
    with Tap([]) as a:
        a.append(1)
        return a
Run Code Online (Sandbox Code Playgroud)

没有绕过return声明,with在这里真的没有做任何事情.但是你Tap在开始时确实有权利,这可以让你知道我想要的功能是什么.它比使用lambdas更好,因为你不仅限于表达式,并且在with语句中可以有你想要的任何东西.

总的来说,我会说,如果你想要tap那么糟糕,那么坚持使用ruby,如果你需要在python中编程,使用python来编写python而不是ruby.当我开始学习ruby时,我打算写ruby;)

  • 由于带有`with`语句而创建的变量在`with`块之后的代码中仍然可见,因此您可以将`return`拉回到一级缩进.然后我认为你有一个Python` tap` - 一些代码,其唯一的目的是增加一些函数调用开销和另一个缩进级别. (2认同)