Что есть у Ruby, чего нет у Python, и наоборот?
Существует много дискуссий о Python против Ruby, и я все нахожу их совершенно бесполезными, потому что все они оборачиваются тем, почему функция X отстой в языке Y или что утверждают, что язык Y не имеет X, хотя на самом деле это так. Я также точно знаю, почему я предпочитаю Python, но это также субъективно и не поможет никому выбрать, поскольку у них могут не быть те же вкусы в разработке, что и у меня.
Поэтому было бы интересно перечислить различия объективно. Так что никакие "лямбды Python" - отстой ". Вместо этого объясните, что может делать лямбда-труба Ruby, что не может Python. Нет субъективности. Пример кода это хорошо!
Не имейте несколько различий в одном ответе, пожалуйста. И проголосуйте за тех, кого вы знаете, правильно, и за тех, кого вы знаете, неправильно (или субъективно). Также различия в синтаксисе не интересны. Мы знаем, что Python делает с отступом то, что Ruby делает с помощью скобок и концов, и что в Python @ называется self.
ОБНОВЛЕНИЕ: Теперь это вики сообщества, поэтому мы можем добавить большие различия здесь.
Ruby has a class reference in the class bodyВ Ruby у вас есть ссылка на класс (self) уже в теле класса. В Python у вас нет ссылки на класс до тех пор, пока не будет завершено построение класса.
Пример:
class Kaka
puts self
end
В этом случае self - это класс, и этот код выведет «Kaka». Невозможно распечатать имя класса или каким-либо другим способом получить доступ к классу из тела определения класса в Python (вне определения метода).
All classes are mutable in RubyЭто позволяет вам разрабатывать расширения для основных классов. Вот пример расширения рельсов:
class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end
Python (представьте, что не было''.startswith
метод):
def starts_with(s, prefix):
return s[:len(prefix)] == prefix
Вы можете использовать его в любой последовательности (не только в строках). Для того, чтобы использовать его, вы должны импортировать егоexplicitly например.,from some_module import starts_with
.
В Ruby есть регулярные выражения первого класса, переменные $, переменный цикл построчного ввода awk / perl и другие функции, которые делают его более подходящим для написания небольших сценариев оболочки, которые разбирают текстовые файлы или действуют как связующий код для других программ.
Ruby has first class continuationsБлагодаря заявлению callcc. В Python вы можете создавать продолжения различными способами, но в язык не встроена поддержка.
Ruby has blocksС помощью "do" С помощью оператора вы можете создать многострочную анонимную функцию в Ruby, которая будет передана в качестве аргумента в метод перед do и будет вызываться оттуда. В Python вы бы вместо этого делали это либо передавая метод, либо с помощью генераторов.
Рубин:
amethod { |here|
many=lines+of+code
goes(here)
}
Python (блоки Ruby соответствуют различным конструкциям в Python):
with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)
Или же
for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)
Или же
def function(here):
many=lines+of+code
goes(here)
amethod(function) # `function` is a callback
Интересно, что в Ruby оператор удобства для вызова блока называется «yield», который в Python создаст генератор.
Рубин:
def themethod
yield 5
end
themethod do |foo|
puts foo
end
Python:
def themethod():
yield 5
for foo in themethod():
print foo
Хотя принципы разные, результат поразительно похож.
Ruby supports functional style (pipe-like) programming more easilymyList.map(&:description).reject(&:empty?).join("\n")
Python:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Python has built-in generators (which are used like Ruby blocks, as noted above)
В Python есть поддержка генераторов на языке. В Ruby 1.8 вы можете использовать модуль генератора, который использует продолжения для создания генератора из блока. Или вы можете просто использовать блок / proc / lambda! Более того, в Ruby 1.9 Fibres являются и могут использоваться как генераторы, а класс Enumerator является встроенным генератором.4
docs.python.org имеет этот пример генератора:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
Сравните это с приведенными выше примерами блоков.
Python has flexible name space handlingВ Ruby, когда вы импортируете файл сrequire
все вещи, определенные в этом файле, окажутся в вашем глобальном пространстве имен. Это вызывает загрязнение пространства имен. Решением для этого являются модули Rubys. Но если вы создаете пространство имен с модулем, то вы должны использовать это пространство имен для доступа к содержащимся классам.
В Python файл является модулем, и вы можете импортировать содержащиеся в нем имена с помощьюfrom themodule import *
тем самым загрязняя пространство имен, если хотите. Но вы также можете импортировать только выбранные имена сfrom themodule import aname, another
или вы можете простоimport themodule
а затем получить доступ к именам сthemodule.aname
, Если вам нужно больше уровней в вашем пространстве имен, вы можете иметь пакеты, которые являются каталогами с модулями и__init__.py
файл.
Строки документации - это строки, которые присоединяются к модулям, функциям и методам и могут быть самоанализ во время выполнения. Это помогает создавать такие вещи, как команда справки и автоматическая документация.
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
Эквивалент Ruby аналогичен javadoc и расположен над методом, а не внутри него. Они могут быть извлечены во время выполнения из файлов, используя метод 1.9 # source_locationпример использования
Python has multiple inheritanceRuby не («специально» - см. Веб-сайт Ruby,посмотрите, как это делается в Ruby). Он повторно использует концепцию модуля как тип абстрактных классов.
Python has list/dict comprehensionsPython:
res = [x*x for x in range(1, 10)]
Рубин:
res = (0..9).map { |x| x * x }
Python:
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Рубин:
p = proc { |x| x * x }
(0..9).map(&p)
питон2.7+:
>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}
Рубин:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Python has decorators
Вещи, подобные декораторам, также могут быть созданы в Ruby, и также можно утверждать, что они не так необходимы, как в Python.
Syntax differencesRuby требует & quot; конец & quot; или & quot;} & quot; закрыть все свои области, в то время как Python использует только пробелы. В Ruby недавно предпринимались попытки разрешить использование только пробеловhttp://github.com/michaeledgar/seamless