264 votos

¿Qué tiene Ruby que Python no lo hace, y viceversa?

Hay un montón de discusiones de Python Ruby, y yo todos ellos completamente ineficiente, debido a que todo gire en torno a por qué la función X chupa en el lenguaje Y, o que la reclamación de idioma Y no tiene X, aunque de hecho lo hace. También sé exactamente por qué prefiero Python, pero que también es subjetivo, y no ayuda a nadie elección, ya que pueden no tener los mismos gustos en desarrollo, como yo.

Por lo tanto, sería interesante la lista de las diferencias, de manera objetiva. Por lo que no "Python lambdas chupa". En lugar de explicar lo de Ruby lambdas puede hacer que Python no puede. No hay subjetividad. Ejemplo de código es bueno!

No se tienen varias diferencias en una respuesta, por favor. Y votar las que sabes que son correctos, y abajo de esos que sabemos que son incorrectas (o subjetivas). Además, las diferencias en la sintaxis no es muy interesante. Sabemos Python hace con sangría lo que Ruby se hace con los soportes y los extremos, y que @ se llama a sí mismo en Python.

ACTUALIZACIÓN: Esto es ahora una wiki de la comunidad, por lo que podemos añadir las grandes diferencias aquí.

Ruby tiene una referencia de la clase en el cuerpo de la clase

En Ruby tiene una referencia a la clase de (auto) ya en el cuerpo de la clase. En Python no tiene una referencia a la clase hasta después de que la clase termine la construcción.

Un ejemplo:

class Kaka
  puts self
end

yo en este caso, es la clase, y que este código imprimir "Kaká". No hay manera de imprimir el nombre de la clase o en otras formas de acceder a la clase desde la definición de la clase de cuerpo en Python (fuera de las definiciones de método).

Todas las clases son mutables en Rubí

Esto permite desarrollar extensiones de las clases básicas. He aquí un ejemplo de un rieles de extensión:

class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

Python (imagino que no hubo ''.startswith método):

def starts_with(s, prefix):
    return s[:len(prefix)] == prefix

Usted puede usarlo en cualquier secuencia (no sólo de las cadenas). Con el fin de utilizar lo que debe importar es explícitamente por ej., from some_module import starts_with.

Ruby ha Perl-como características de secuencias de comandos

Rubí de primera clase regex, $variables, el awk/perl línea por línea de entrada de bucle y otras características que hacen que sea más adecuado para la escritura de pequeños scripts de shell que munge archivos de texto o actuar como pegamento código para otros programas.

Rubí de primera clase continuaciones

Gracias a la callcc declaración. En Python se pueden crear las continuaciones por varias técnicas, pero no hay ningún apoyo incorporadas en el lenguaje.

Ruby ha bloques

Con el "hacer" estado de cuenta, puede crear una multi-línea de función anónima en Ruby, que se pasa como un argumento en el método en frente de hacerlo, y llamar desde allí. En Python sería en lugar de hacer esto, ya sea por el paso de un método o de los generadores.

Ruby:

amethod { |here|
    many=lines+of+code
    goes(here)
}

Python Ruby bloques corresponden a diferentes construcciones en Python):

with amethod() as here: # `amethod() is a context manager
    many=lines+of+code
    goes(here)

O

for here in amethod(): # `amethod()` is an iterable
    many=lines+of+code
    goes(here)

O

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

Curiosamente, la conveniencia de la declaración en Ruby para llamar a un bloque que se llama "rendimiento", lo que en Python se creará un generador.

Ruby:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

def themethod():
    yield 5

for foo in themethod():
    print foo

Aunque los principios son diferentes, el resultado es sorprendentemente similar.

Ruby admite estilo funcional (pipe) de programación más fácilmente

myList.map(&:description).reject(&:empty?).join("\n")

Python:

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))

Python se ha incorporado en los generadores, los cuales son utilizados como Ruby bloques, como se señaló anteriormente)

Python tiene soporte para los generadores en el lenguaje. En Ruby 1.8 usted puede utilizar el módulo del generador que utiliza a continuación para crear un generador de un bloque. O, usted podría utilizar un bloque de/proc/lambda! Por otra parte, en Ruby 1.9 Fibras, y puede ser utilizada como generadores, y la clase de Enumerador es un generador integrado 4

docs.python.org ha este generador ejemplo:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

Esto contrasta con el anterior bloque de ejemplos.

Python tiene flexible de espacio de nombre de manipulación

En Ruby, cuando se importa un archivo require, todas las cosas se definen en el archivo va a terminar en el espacio de nombres global. Esto hace que el espacio de nombres de la contaminación. La solución a la que se Rubys módulos. Pero si se crea un espacio de nombres con un módulo, entonces usted tiene que utilizar el espacio de nombres para el acceso a los contenidos de las clases.

En Python, el archivo es un módulo, y puede importar sus contenidos nombres con from themodule import *, lo que contamina el espacio de nombres si lo desea. Pero también puede importar sólo los nombres seleccionados con from themodule import aname, another o puede, simplemente, import themodule y, a continuación, acceder a los nombres con themodule.aname. Si desea más niveles en el espacio de nombres puede haber paquetes, que son directorios con módulos y un __init__.py archivo.

Python tiene docstrings

Docstrings son cadenas que están conectados a los módulos, funciones y métodos, y puede ser inspeccionar en tiempo de ejecución. Esto ayuda para la creación de tales cosas como el comando de ayuda y documentación automática.

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

Ruby es el equivalente son similares a los javadocs, y situado sobre el método en lugar de dentro de ella. De que puedan ser recuperados en el tiempo de ejecución de los archivos mediante 1.9 del Método#source_location ejemplo de uso

Python tiene la herencia múltiple

Ruby no ("a propósito" -- ver Ruby de la web, ver aquí cómo se hace en Ruby). No reutilizar el concepto de módulo como un tipo de clases abstractas.

Python tiene lista/dict comprensiones de

Python:

res = [x*x for x in range(1, 10)]

Ruby:

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]

Ruby:

p = proc { |x| x * x }
(0..9).map(&p)

Python 2.7+:

>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}

Ruby:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}

Python tiene decoradores

Cosas similares a los decoradores pueden ser creadas en Ruby, y también se puede argumentar que no son tan necesarias como en Python.

Las diferencias en la sintaxis

Ruby requiere "final" o "}" para cerrar todos sus ámbitos, mientras que Python utiliza espacio en blanco solamente. Ha habido intentos recientes en Ruby para permitir espacios en blanco sólo sangría http://github.com/michaeledgar/seamless

34voto

John Feminella Puntos 116878

Ruby tiene los conceptos de bloques, que son esencialmente azúcar sintáctico en torno a una sección de código, que son una forma de crear cierres y pasar a otro método que puede o no puede utilizar el bloque. Un bloque puede ser invocada posteriormente a través de un yield declaración.

Por ejemplo, una simple definición de un each método en Array podría ser algo como:

class Array
  def each
    for i in self  
      yield(i)     # If a block has been passed, control will be passed here.
    end  
  end  
end

A continuación, puedes invocar esta así:

# Add five to each element.
[1, 2, 3, 4].each{ |e| puts e + 5 }
> [6, 7, 8, 9]

Python tiene funciones anónimas/cierres/lambdas, pero no muy a tener bloques, ya que faltan algunos de los útiles azúcar sintáctico. Sin embargo, existe al menos una manera de conseguirlo de una manera ad-hoc de la moda. Véase, por ejemplo, aquí.

28voto

Glenn Maynard Puntos 24451

Python Ejemplo

Las funciones son de primera clase de las variables en Python. Se puede declarar una función, pase alrededor de un objeto, y sobrescribir:

def func(): print "hello"
def another_func(f): f()
another_func(func)

def func2(): print "goodbye"
func = func2

Esta es una característica fundamental de los modernos lenguajes de secuencias de comandos. JavaScript y Lua hacer esto, también. Ruby no tratar de las funciones de este camino; nombrar a una de las llamadas de función.

Por supuesto, hay maneras de hacer estas cosas en Ruby, pero no son de primera clase de operaciones. Por ejemplo, puede ajustar una función con Proc.new de tratarla como una variable, pero entonces ya no es una función; es un objeto con una "llamada" método.

Ruby funciones no son objetos de primera clase

Ruby funciones no son objetos de primera clase. Las funciones deben estar envueltos en un objeto para pasar alrededor de ellos; el objeto resultante no puede ser tratada como una función. Las funciones no pueden ser asignados en primera clase de una manera; en su lugar, una función de su objeto contenedor debe ser llamado a modificar.

def func; p "Hello" end
def another_func(f); method(f)[] end
another_func(:func)      # => "Hello"

def func2; print "Goodbye!"
self.class.send(:define_method, :func, method(:func2))
func                     # => "Goodbye!"

method(:func).owner      # => Object
func                     # => "Goodbye!"
self.func                # => "Goodbye!"    

26voto

Mark Thomas Puntos 19281

En última instancia, todas las respuestas van a ser subjetivo en algún nivel, y las respuestas publicado hasta el momento bastante probar que usted no puede apuntar a cualquier característica que no es factible en el otro idioma, en un igual de agradable (si no similar), ya que ambos idiomas son muy conciso y expresivo.

Me gusta la sintaxis de Python. Sin embargo, usted tiene que cavar un poco más profundo que la sintaxis para encontrar la verdadera belleza de Ruby. Hay zenlike belleza en Rubí de la consistencia. Mientras que no hay ejemplo trivial, posiblemente, puede explicar esto por completo, voy a tratar de venir para arriba con los de aquí sólo para explicar lo que quiero decir.

Revertir las palabras en esta cadena:

sentence = "backwards is sentence This"

Cuando usted piensa acerca de cómo habría que hacerlo, tendría que hacer lo siguiente:

  1. Dividir la frase en palabras
  2. Revertir las palabras
  3. Re-unir las palabras en una cadena

En Ruby, que había de hacer esto:

sentence.split.reverse.join ' '

Exactamente como usted piensa acerca de ello, en la misma secuencia, una llamada a un método tras otro.

En python, que se parecen más a esto:

" ".join(reversed(sentence.split()))

No es difícil de entender, pero no muy a tener el mismo flujo. El sujeto (la frase) se entierra en el medio. Las operaciones son una mezcla de funciones y métodos del objeto. Este es un ejemplo trivial, pero uno descubre muchos ejemplos diferentes cuando realmente el trabajo y la comprensión del Rubí, especialmente en tareas no triviales.

19voto

Jason Baker Puntos 56682

Python tiene una mentalidad de "todos somos adultos aquí". Por lo tanto, usted encontrará que Ruby tiene cosas como constantes, mientras que Python no hace (aunque constantes de Rubí sólo plantean una advertencia). La forma en Python de pensar es que si quieres hacer algo constante, usted debe poner los nombres de las variables en mayúsculas y no cambiarlo.

Por ejemplo, Ruby:

 >> PI = 3.14
=> 3.14
>> PI += 1
(irb):2: warning: already initialized constant PI
=> 4.14
 

Python:

 >>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006
 

18voto

Tempus Puntos 22972

Sólo puede importar funciones específicas de un módulo en Python. En Ruby, y de importar la totalidad de la lista de métodos. Usted podría "unimport" en Ruby, pero no lo es.

EDICIÓN:

vamos a tomar esto de Ruby módulo :


module Whatever
  def method1
  end

  def method2
  end
end

si la incluye en su código :


include Whatever

verá que ambos method1 y method2 ha sido añadido a su espacio de nombres. No se puede importar sólo method1. Usted importación de ellos tanto o no importar en absoluto. En Python se pueden importar sólo los métodos de su elección. Si esto tendría un nombre que tal vez sería llamada selectiva importar?

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: