我非常了解Ruby.我相信我现在可能需要学习Python.对于那些了解两者的人来说,两者之间的概念是相似的,哪些是不同的?
我正在寻找一个类似于我为JavaScripters学习Lua所做的入门的列表:简单的事情,如空白意义和循环结构; nilPython中的名称,以及哪些值被视为"truthy"; 是不是习惯于使用相当于map和each/或笨拙的 东西 ,那些大概是笨拙的常规吗?
如果我得到了各种各样的答案,我很乐意将它们汇总到社区维基中.或者你们都可以互相争斗,试图创造一个真正的综合名单.
编辑:要清楚,我的目标是"正确的"和惯用的Python.如果有一个Python的等价物inject,但是没有人使用它,因为有更好/不同的方法来实现迭代列表和累积结果的常用功能,我想知道你是如何做的.也许我会用一系列共同目标更新这个问题,如何在Ruby中实现它们,并询问Python中的等价物.
Cli*_*ler 152
以下是我的一些主要区别:
Ruby有块; Python没有.
Python有功能; Ruby没有.在Python中,您可以使用任何函数或方法并将其传递给另一个函数.在Ruby中,一切都是方法,方法不能直接传递.相反,你必须将它们包装在Proc中以传递它们.
Ruby和Python都支持闭包,但是以不同的方式.在Python中,您可以在另一个函数中定义一个函数.内部函数具有对外部函数的变量的读访问权,但不具有写访问权.在Ruby中,您可以使用块定义闭包.闭包具有对外部作用域的变量的完全读写访问权限.
Python具有列表推导,它具有很强的表现力.例如,如果您有一个数字列表,则可以编写
[x*x for x in values if x > 15]
Run Code Online (Sandbox Code Playgroud)
获取大于15的所有值的平方的新列表.在Ruby中,您必须编写以下内容:
values.select {|v| v > 15}.map {|v| v * v}
Run Code Online (Sandbox Code Playgroud)
Ruby代码感觉不那么紧凑.它也没有那么高效,因为它首先将values数组转换为包含大于15的值的较短中间数组.然后,它接受中间数组并生成包含中间体方块的最终数组.然后抛出中间阵列.因此,Ruby在计算期间最终在内存中有3个数组; Python只需要输入列表和结果列表.
Python还提供类似的地图理解.
Python支持元组; Ruby没有.在Ruby中,您必须使用数组来模拟元组.
Ruby支持switch/case语句; Python没有.
Ruby支持标准的expr ? val1 : val2三元运算符; Python没有.
Ruby仅支持单继承.如果需要模仿多重继承,可以定义模块并使用mix-ins将模块方法拉入类中.Python支持多重继承而不是模块混合.
Python仅支持单行lambda函数.Ruby块是一种lambda函数,可以任意大.因此,Ruby代码通常以比Python代码更实用的方式编写.例如,要在Ruby中循环遍历列表,通常会这样做
collection.each do |value|
...
end
Run Code Online (Sandbox Code Playgroud)
该块的工作方式非常类似于传递给的函数collection.each.如果你在Python中做同样的事情,你必须定义一个命名的内部函数,然后将其传递给集合中的每个方法(如果列表支持此方法):
def some_operation(value):
...
collection.each(some_operation)
Run Code Online (Sandbox Code Playgroud)
这不是很好.因此,通常在Python中将使用以下非功能方法:
for value in collection:
...
Run Code Online (Sandbox Code Playgroud)在两种语言之间以安全的方式使用资源是完全不同的.这里的问题是你想要分配一些资源(打开文件,获取数据库游标等),对它执行一些任意操作,然后即使发生异常也以安全的方式关闭它.
在Ruby中,因为块非常容易使用(参见#9),所以通常将此模式编码为一种方法,该方法为在资源上执行的任意操作取一个块.
在Python中,传递任意动作的函数有点笨拙,因为你必须编写一个命名的内部函数(参见#9).相反,Python使用with语句来安全地处理资源.请参阅如何正确清理Python对象?更多细节.
Dav*_* J. 27
我花了几个月的时间学习Python,经过6年的Ruby学习.对于这两种语言,确实没有很好的比较,所以我决定自己编写并自己写一个.现在,它是主要关注函数式编程,但既然你提到了Ruby的inject方法,我猜我们是在相同的波长.
我希望这会有所帮助:Python的"丑陋"
有几点会让你朝着正确的方向前进:
您在Ruby中使用的所有函数编程优点都在Python中,它甚至更容易.例如,您可以完全按照您的预期映射函数:
def f(x):
return x + 1
map(f, [1, 2, 3]) # => [2, 3, 4]
Run Code Online (Sandbox Code Playgroud)Python没有像这样的方法each.由于您仅each用于副作用,因此Python中的等效项是for循环:
for n in [1, 2, 3]:
print n
Run Code Online (Sandbox Code Playgroud)当a)你必须一起处理函数和对象集合时b)当你需要使用多个索引进行迭代时,列表理解是很好的.例如,要查找一个字符串的所有回文(假设你有一个函数p()返回的回文真),所有你需要的是一个单一的列表理解:
s = 'string-with-palindromes-like-abbalabba'
l = len(s)
[s[x:y] for x in range(l) for y in range(x,l+1) if p(s[x:y])]
Run Code Online (Sandbox Code Playgroud)irc*_*ell 10
我的建议:不要试图了解差异.了解如何在Python中解决问题.就像对每个问题都有一个Ruby方法(它非常适用于语言的局限性和优势),有一个Python方法来解决这个问题.它们都不同.为了充分利用每种语言,你真的应该学习语言本身,而不仅仅是从一种语言到另一种语言的"翻译".
现在,说到这一点,差异将帮助您更快地适应并对Python程序进行一次修改.这对于开始写作来说很好.但是,尝试从其他项目中学习建筑和设计决策背后的原因,而不是语言语义背后的原因......
小智 8
我知道Ruby很少,但这里有一些关于你提到的事情的要点:
nil,表示缺少值的值将是None(请注意,您要检查它,x is None或者x is not None不是==- 或通过强制转换为布尔值,请参阅下一点).None零式的数字(0,0.0,0j(复数))和空集([],{},set(),空字符串"",等等)被认为falsy,一切被认为是truthy.for- )显式循环.为了生成一堆没有副作用的东西,使用列表推导(或者他们的亲戚 - 懒惰的一次迭代器的生成器表达式,所述集合的dict/set comprehensions).关于循环:你有for一个可迭代的操作(!不计数),并且while可以完成你期望的操作.由于对迭代器的广泛支持,更加强大.不仅几乎所有可以作为迭代器而不是列表的东西都是迭代器(至少在Python 3中 - 在Python 2中,你有两个并且默认是一个列表,遗憾的是).有许多用于处理迭代器的工具 - zip并行迭代任意数量的迭代,enumerate给你(index, item)(在任何可迭代的,而不仅仅是在列表上),甚至切片abritary(可能是大的或无限的)iterables!我发现这些使许多循环任务变得更加简单.毋庸置疑,它们可以很好地与列表推导,生成器表达式等集成.
小智 6
在Ruby中,实例变量和方法完全不相关,除非您明确地将它们与attr_accessor或类似的东西相关联.
在Python中,方法只是一个特殊的属性类:一个是可执行的.
例如:
>>> class foo:
... x = 5
... def y(): pass
...
>>> f = foo()
>>> type(f.x)
<type 'int'>
>>> type(f.y)
<type 'instancemethod'>
Run Code Online (Sandbox Code Playgroud)
这种差异有很多含义,例如,引用fx指的是方法对象,而不是调用它.另外,正如您所看到的,默认情况下fx是公共的,而在Ruby中,默认情况下实例变量是私有的.