python - name - xaxis plotly




Che cosa ha Ruby che Python non ha, e viceversa? (20)

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace.

Con Cargo puoi " richiedere librerie senza ingombrare il tuo spazio dei nomi ".

# foo-1.0.0.rb
class Foo
  VERSION = "1.0.0"
end

# foo-2.0.0.rb
class Foo
  VERSION = "2.0.0"
end
>> Foo1 = import("foo-1.0.0")
>> Foo2 = import("foo-2.0.0")
>> Foo1::VERSION
=> "1.0.0"
>> Foo2::VERSION
=> "2.0.0"

Ci sono molte discussioni su Python vs Ruby, e io le trovo del tutto inutili, perché si girano tutte perché la caratteristica X fa schifo con la lingua Y, o quella lingua di affermazione Y non ha X, anche se in effetti lo fa. So anche esattamente perché preferisco Python, ma anche questo è soggettivo e non aiuterebbe nessuno a scegliere, poiché potrebbero non avere gli stessi gusti nello sviluppo di me.

Sarebbe quindi interessante elencare le differenze, oggettivamente. Quindi niente "il lambdas di Python fa schifo". Spiega invece cosa possono fare i lambda di Ruby che quelli di Python non possono. Nessuna soggettività Il codice di esempio è buono!

Non avere molte differenze in una risposta, per favore. E vota quelli che sai essere corretti, e quelli che conosci non sono corretti (o sono soggettivi). Inoltre, le differenze nella sintassi non sono interessanti. Sappiamo che Python fa con indentazione ciò che Ruby fa con parentesi e finisce, e che @ è chiamato self in Python.

AGGIORNAMENTO: Questo è ora un wiki della comunità, quindi possiamo aggiungere qui le grandi differenze.

Ruby ha un riferimento di classe nel corpo della classe

In Ruby hai un riferimento alla classe (il sé) già nel corpo della classe. In Python non hai un riferimento alla classe fino a quando la costruzione della classe non è terminata.

Un esempio:

class Kaka
  puts self
end

il sé in questo caso è la classe, e questo codice stamperebbe "Kaka". Non c'è modo di stampare il nome della classe o in altri modi accedere alla classe dal corpo della definizione di classe in Python (al di fuori delle definizioni dei metodi).

Tutte le classi sono mutabili in Ruby

Ciò ti consente di sviluppare estensioni alle classi principali. Ecco un esempio di estensione di un binario:

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

Python (immagina che non ci siano ''.startswith "):

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

Potresti usarlo su qualsiasi sequenza (non solo stringhe). Per usarlo devi importarlo esplicitamente ad es., from some_module import starts_with .

Ruby ha caratteristiche di scripting tipo Perl

Ruby ha espressioni regolari di prima classe, $ -variables, il ciclo di input riga per riga awk / perl e altre caratteristiche che lo rendono più adatto alla scrittura di piccoli script di shell che munge i file di testo o agiscono come codice di colla per altri programmi.

Ruby ha continuazioni di prima classe

Grazie alla dichiarazione callcc. In Python puoi creare continuazioni con varie tecniche, ma non c'è supporto integrato nella lingua.

Ruby ha blocchi

Con la dichiarazione "do" è possibile creare una funzione anonima a più righe in Ruby, che verrà passata come argomento nel metodo prima di fare e richiamata da lì. In Python invece dovresti farlo passando un metodo o con generatori.

Rubino:

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

Python (i blocchi Ruby corrispondono a diversi costrutti in 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

È interessante notare che la dichiarazione di convenienza in Ruby per chiamare un blocco si chiama "yield", che in Python creerà un generatore.

Rubino:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Pitone:

def themethod():
    yield 5

for foo in themethod():
    print foo

Sebbene i principi siano diversi, il risultato è sorprendentemente simile.

Ruby supporta la programmazione in stile funzionale (pipe-like) più facilmente

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

Pitone:

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

Python ha generatori integrati (che sono usati come blocchi di Ruby, come notato sopra)

Python supporta i generatori nella lingua. In Ruby 1.8 è possibile utilizzare il modulo generatore che utilizza le continuazioni per creare un generatore da un blocco. Oppure potresti semplicemente usare un blocco / proc / lambda! Inoltre, in Ruby 1.9 le fibre sono e possono essere utilizzate come generatori e la classe Enumerator è un generatore integrato 4

docs.python.org ha questo esempio generatore:

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

Contrastare questo con gli esempi di blocco sopra.

Python ha una gestione flessibile dei nomi

In Ruby, quando importi un file con require , tutte le cose definite in quel file finiranno nel tuo spazio dei nomi globale. Ciò causa inquinamento dello spazio dei nomi. La soluzione a questo è i moduli Rubys. Ma se crei uno spazio dei nomi con un modulo, devi usare quel namespace per accedere alle classi contenute.

In Python, il file è un modulo ed è possibile importare i suoi nomi contenuti con from themodule import * , in tal modo inquinando lo spazio dei nomi, se lo si desidera. Ma puoi anche importare solo i nomi selezionati con il from themodule import aname, another o semplicemente import themodule e quindi accedere ai nomi con themodule.aname . Se vuoi più livelli nel tuo spazio dei nomi, puoi avere dei pacchetti, che sono directory con moduli e un file __init__.py .

Python ha docstring

Le stringhe sono stringhe collegate a moduli, funzioni e metodi e possono essere introspezionate in fase di runtime. Questo aiuta a creare cose come il comando di aiuto e la documentazione automatica.

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

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

L'equivalente di Ruby è simile a javadocs e si trova sopra il metodo anziché all'interno di esso. Possono essere recuperati in fase di runtime dai file usando l' uso di esempio di # metodo # source_location 1.9

Python ha ereditarietà multipla

Ruby no ("apposta" - vedi il sito web di Ruby, vedi qui come è fatto in Ruby ). Riusa il concetto di modulo come un tipo di classi astratte.

Python ha una lista / dict di comprensione

Pitone:

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

Rubino:

res = (0..9).map { |x| x * x }

Pitone:

>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Rubino:

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'}

Rubino:

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

Python ha decoratori

Cose simili ai decoratori possono anche essere create in Ruby, e si può anche sostenere che non sono necessarie come in Python.

Differenze di sintassi

Ruby richiede "end" o "}" per chiudere tutti i suoi ambiti, mentre Python utilizza solo lo spazio bianco. Ci sono stati recenti tentativi in ​​Ruby di consentire la sola indentazione di spazi bianchi http://github.com/michaeledgar/seamless


Esempio di Python

Le funzioni sono variabili di prima classe in Python. Puoi dichiarare una funzione, passarla come oggetto e sovrascriverla:

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

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

Questa è una caratteristica fondamentale dei moderni linguaggi di scripting. Anche JavaScript e Lua fanno questo. Ruby non tratta le funzioni in questo modo; nominare una funzione lo chiama.

Certo, ci sono modi per fare queste cose in Ruby, ma non sono operazioni di prima classe. Ad esempio, puoi racchiudere una funzione con Proc.new per trattarla come una variabile, ma poi non è più una funzione; è un oggetto con un metodo "call".

Le funzioni di Ruby non sono oggetti di prima classe

Le funzioni di Ruby non sono oggetti di prima classe. Le funzioni devono essere racchiuse in un oggetto per passarle in giro; l'oggetto risultante non può essere trattato come una funzione. Le funzioni non possono essere assegnate in un modo di prima classe; invece, una funzione nel suo oggetto contenitore deve essere chiamata per modificarli.

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!"    

È possibile importare solo funzioni specifiche da un modulo in Python. In Ruby, importi l'intero elenco di metodi. Potresti "non importarli" in Ruby, ma non è tutto.

MODIFICARE:

prendiamo questo modulo Ruby:


module Whatever
  def method1
  end

  def method2
  end
end

se lo includi nel tuo codice:


include Whatever

vedrai che sia method1 che method2 sono stati aggiunti al tuo spazio dei nomi. Non è possibile importare solo method1 . Li importi entrambi o non li importi affatto. In Python puoi importare solo i metodi che hai scelto. Se questo avesse un nome forse si chiamerebbe importazione selettiva?


Alla fine tutte le risposte saranno soggettive a un certo livello, e le risposte pubblicate finora dimostrano che non è possibile indicare alcuna caratteristica che non è fattibile nell'altra lingua in un modo altrettanto bello (se non simile) , poiché entrambe le lingue sono molto concise ed espressive.

Mi piace la sintassi di Python. Tuttavia, devi scavare un po 'più in profondità della sintassi per trovare la vera bellezza di Ruby. C'è una bellezza zen nella consistenza di Ruby. Mentre nessun esempio banale può spiegarlo completamente, cercherò di inventarne uno solo per spiegare cosa intendo.

Invertire le parole in questa stringa:

sentence = "backwards is sentence This"

Quando pensi a come lo faresti, dovresti fare quanto segue:

  1. Dividi la frase in parole
  2. Invertire le parole
  3. Riunisci nuovamente le parole in una stringa

In Ruby, dovresti fare questo:

sentence.split.reverse.join ' '

Esattamente come ci pensi, nella stessa sequenza, un metodo chiama dopo l'altro.

In Python, sarebbe più simile a questo:

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

Non è difficile da capire, ma non ha lo stesso flusso. Il soggetto (frase) è sepolto nel mezzo. Le operazioni sono un mix di funzioni e metodi di oggetti. Questo è un esempio banale, ma si scoprono molti esempi diversi quando si lavora e si comprende veramente Ruby, specialmente in attività non banali.


Dal website di Ruby:

Somiglianze Come con Python, in Ruby, ...

  • C'è un prompt interattivo (chiamato irb).
  • Puoi leggere i documenti sulla riga di comando (con il comando ri invece di pydoc).
  • Non ci sono terminatori di riga speciali (eccetto la solita nuova riga).
  • I valori letterali stringa possono estendersi su più righe come le stringhe con quotatura tripla di Python.
  • Le parentesi sono per gli elenchi e le parentesi sono per dict (che in Ruby sono chiamate "hash").
  • Gli array funzionano allo stesso modo (aggiungendoli crea un array lungo, ma componendoli in questo modo a3 = [ a1, a2 ] fornisce una matrice di matrici).
  • Gli oggetti sono tipizzati in modo forte e dinamico.
  • Tutto è un oggetto e le variabili sono solo riferimenti a oggetti.
  • Sebbene le parole chiave siano un po 'diverse, le eccezioni funzionano allo stesso modo.
  • Hai strumenti di documentazione incorporati (Ruby's è chiamato rdoc).

Differenze a differenza di Python, in Ruby, ...

  • Le stringhe sono mutabili.
  • Puoi creare costanti (variabili di cui non intendi cambiare il valore).
  • Esistono alcune convenzioni sui casi forzate (ad esempio i nomi delle classi iniziano con una lettera maiuscola, le variabili iniziano con una lettera minuscola).
  • C'è solo un tipo di contenitore di lista (una matrice) ed è mutabile.
  • Le stringhe tra virgolette consentono sequenze di escape (come \ t) e una speciale sintassi di "sostituzione di espressione" (che consente di inserire i risultati delle espressioni di Ruby direttamente in altre stringhe senza dover "aggiungere" + "stringhe" + "insieme") . Le stringhe con quotatura singola sono come le "stringhe raw" di Python.
  • Non ci sono classi "new style" e "old style". Solo un tipo.
  • Non si accede mai direttamente agli attributi. Con Ruby, sono tutte le chiamate di metodo.
  • Le parentesi per le chiamate ai metodi sono in genere facoltative.
  • C'è pubblico, privato e protetto per forzare l'accesso, invece di _voluntary_ underscore __convention__ di Python.
  • "Mixin's" sono usati al posto dell'ereditarietà multipla.
  • È possibile aggiungere o modificare i metodi delle classi integrate. Entrambi i linguaggi consentono di aprire e modificare le classi in qualsiasi momento, ma Python impedisce la modifica dei built-in - Ruby no.
  • Hai true e false invece di True e False (e nil invece di None).
  • Quando vengono testati per la verità, solo il falso e il nulla valgono di un valore falso. Tutto il resto è vero (compresi 0, 0.0, "" e []).
  • È elsif invece di elif.
  • È necessario invece di importare. Altrimenti, tuttavia, l'utilizzo è lo stesso.
  • I soliti commenti in stile sulla linea (s) sopra le cose (invece di docstring sotto di loro) sono utilizzati per la generazione di documenti.
  • Ci sono una serie di scorciatoie che, sebbene ti danno più da ricordare, impari velocemente. Tendono a rendere Ruby divertente e molto produttivo.

Non penso che "Ruby abbia X e Python no, mentre Python ha Y e Ruby no" è il modo più utile per guardarlo. Sono lingue abbastanza simili, con molte abilità condivise.

In larga misura, la differenza è ciò che la lingua rende elegante e leggibile. Per usare un esempio che hai sollevato, entrambi teoricamente hanno lambda, ma i programmatori Python tendono ad evitarli, e i costrutti fatti usando non sembrano affatto leggibili o idiomatici come in Ruby. Quindi in Python, un buon programmatore vorrà intraprendere un percorso diverso per risolvere il problema rispetto a quello che avrebbe in Ruby, solo perché in realtà è il modo migliore per farlo.


Python ha una sintassi esplicita e incorporata per le compilation e i generatori di elenchi, mentre in Ruby si usano i blocchi di mappa e di codice.

Confrontare

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

a

res = (1..10).map{ |x| x*x }

Ruby ha i concetti di blocchi , che sono essenzialmente zucchero sintattico attorno a una sezione di codice; sono un modo per creare chiusure e passarle a un altro metodo che può o non può usare il blocco. Un blocco può essere invocato in seguito attraverso una dichiarazione di yield .

Ad esempio, una semplice definizione di each metodo su Array potrebbe essere qualcosa del tipo:

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

Quindi puoi invocare questo in questo modo:

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

Python ha funzioni anonime / chiusure / lambda, ma non ha abbastanza blocchi poiché manca un po 'dello zucchero sintattico utile. Tuttavia, c'è almeno un modo per farlo in modo ad hoc. Vedi, per esempio, here .


Vorrei suggerire una variante della domanda originale, "Che cosa ha Ruby che Python non ha, e viceversa?" che ammette la risposta deludente, "Bene, cosa puoi fare con Ruby o Python che non possono essere fatti in Intercal?" Niente a quel livello, perché Python e Ruby fanno entrambi parte della vasta famiglia reale seduta sul trono di essere Turing approssimativa.

Ma che dire di questo:

Cosa può essere fatto con grazia e bene in Python che non può essere fatto in Ruby con tale bellezza e buona ingegneria, o viceversa?

Potrebbe essere molto più interessante del mero confronto di funzionalità.



Copia / incolla senza vergogna da: Alex Martelli rispondi sul thread " Cosa c'è di meglio di Ruby than Python " dalla mailing list comp.lang.python .

18 agosto 2003, 10:50 Erik Max Francis ha scritto:

"Brandon J. Van Every" ha scritto:

Cosa c'è di meglio di Ruby rispetto a Python? Sono sicuro che c'è qualcosa. Che cos'è?

Non avrebbe molto più senso chiedere a Ruby la gente, piuttosto che la gente di Python?

Might, or might not, depending on one's purposes -- for example, if one's purposes include a "sociological study" of the Python community, then putting questions to that community is likely to prove more revealing of information about it, than putting them elsewhere:-).

Personally, I gladly took the opportunity to follow Dave Thomas' one-day Ruby tutorial at last OSCON. Below a thin veneer of syntax differences, I find Ruby and Python amazingly similar -- if I was computing the minimum spanning tree among just about any set of languages, I'm pretty sure Python and Ruby would be the first two leaves to coalesce into an intermediate node:-).

Sure, I do get weary, in Ruby, of typing the silly "end" at the end of each block (rather than just unindenting) -- but then I do get to avoid typing the equally-silly ':' which Python requires at the start of each block, so that's almost a wash:-). Other syntax differences such as '@foo' versus 'self.foo', or the higher significance of case in Ruby vs Python, are really just about as irrelevant to me.

Others no doubt base their choice of programming languages on just such issues, and they generate the hottest debates -- but to me that's just an example of one of Parkinson's Laws in action (the amount on debate on an issue is inversely proportional to the issue's actual importance).

Edit (by AM 6/19/2010 11:45): this is also known as "painting the bikeshed" (or, for short, "bikeshedding") -- the reference is, again, to Northcote Parkinson, who gave "debates on what color to paint the bikeshed" as a typical example of "hot debates on trivial topics". (end-of-Edit).

One syntax difference that I do find important, and in Python's favor -- but other people will no doubt think just the reverse -- is "how do you call a function which takes no parameters". In Python (like in C), to call a function you always apply the "call operator" -- trailing parentheses just after the object you're calling (inside those trailing parentheses go the args you're passing in the call -- if you're passing no args, then the parentheses are empty). This leaves the mere mention of any object, with no operator involved, as meaning just a reference to the object -- in any context, without special cases, exceptions, ad-hoc rules, and the like. In Ruby (like in Pascal), to call a function WITH arguments you pass the args (normally in parentheses, though that is not invariably the case) -- BUT if the function takes no args then simply mentioning the function implicitly calls it. This may meet the expectations of many people (at least, no doubt, those whose only previous experience of programming was with Pascal, or other languages with similar "implicit calling", such as Visual Basic) -- but to me, it means the mere mention of an object may EITHER mean a reference to the object, OR a call to the object, depending on the object's type -- and in those cases where I can't get a reference to the object by merely mentioning it I will need to use explicit "give me a reference to this, DON'T call it!" operators that aren't needed otherwise. I feel this impacts the "first-classness" of functions (or methods, or other callable objects) and the possibility of interchanging objects smoothly. Therefore, to me, this specific syntax difference is a serious black mark against Ruby -- but I do understand why others would thing otherwise, even though I could hardly disagree more vehemently with them:-).

Below the syntax, we get into some important differences in elementary semantics -- for example, strings in Ruby are mutable objects (like in C++), while in Python they are not mutable (like in Java, or I believe C#). Again, people who judge primarily by what they're already familiar with may think this is a plus for Ruby (unless they're familiar with Java or C#, of course:-). Me, I think immutable strings are an excellent idea (and I'm not surprised that Java, independently I think, reinvented that idea which was already in Python), though I wouldn't mind having a "mutable string buffer" type as well (and ideally one with better ease-of-use than Java's own "string buffers"); and I don't give this judgment because of familiarity -- before studying Java, apart from functional programming languages where all data are immutable, all the languages I knew had mutable strings -- yet when I first saw the immutable-string idea in Java (which I learned well before I learned Python), it immediately struck me as excellent, a very good fit for the reference-semantics of a higher level programming language (as opposed to the value-semantics that fit best with languages closer to the machine and farther from applications, such as C) with strings as a first-class, built-in (and pretty crucial) data type.

Ruby does have some advantages in elementary semantics -- for example, the removal of Python's "lists vs tuples" exceedingly subtle distinction. But mostly the score (as I keep it, with simplicity a big plus and subtle, clever distinctions a notable minus) is against Ruby (eg, having both closed and half-open intervals, with the notations a..b and a...b [anybody wants to claim that it's obvious which is which?-)], is silly -- IMHO, of course!). Again, people who consider having a lot of similar but subtly different things at the core of a language a PLUS, rather than a MINUS, will of course count these "the other way around" from how I count them:-).

Don't be misled by these comparisons into thinking the two languages are very different, mind you. They aren't. But if I'm asked to compare "capelli d'angelo" to "spaghettini", after pointing out that these two kinds of pasta are just about undistinguishable to anybody and interchangeable in any dish you might want to prepare, I would then inevitably have to move into microscopic examination of how the lengths and diameters imperceptibly differ, how the ends of the strands are tapered in one case and not in the other, and so on -- to try and explain why I, personally, would rather have capelli d'angelo as the pasta in any kind of broth, but would prefer spaghettini as the pastasciutta to go with suitable sauces for such long thin pasta forms (olive oil, minced garlic, minced red peppers, and finely ground anchovies, for example - but if you sliced the garlic and peppers instead of mincing them, then you should choose the sounder body of spaghetti rather than the thinner evanescence of spaghettini, and would be well advised to forego the achovies and add instead some fresh spring basil [or even -- I'm a heretic...! -- light mint...] leaves -- at the very last moment before serving the dish). Ooops, sorry, it shows that I'm traveling abroad and haven't had pasta for a while, I guess. But the analogy is still pretty good!-)

So, back to Python and Ruby, we come to the two biggies (in terms of language proper -- leaving the libraries, and other important ancillaries such as tools and environments, how to embed/extend each language, etc, etc, out of it for now -- they wouldn't apply to all IMPLEMENTATIONS of each language anyway, eg, Jython vs Classic Python being two implementations of the Python language!):

  1. Ruby's iterators and codeblocks vs Python's iterators and generators;

  2. Ruby's TOTAL, unbridled "dynamicity", including the ability
    to "reopen" any existing class, including all built-in ones, and change its behavior at run-time -- vs Python's vast but bounded dynamicity, which never changes the behavior of existing built-in classes and their instances.

Personally, I consider 1 a wash (the differences are so deep that I could easily see people hating either approach and revering the other, but on MY personal scales the pluses and minuses just about even up); and 2 a crucial issue -- one that makes Ruby much more suitable for "tinkering", BUT Python equally more suitable for use in large production applications. It's funny, in a way, because both languages are so MUCH more dynamic than most others, that in the end the key difference between them from my POV should hinge on that -- that Ruby "goes to eleven" in this regard (the reference here is to "Spinal Tap", of course). In Ruby, there are no limits to my creativity -- if I decide that all string comparisons must become case-insensitive, I CAN DO THAT ! Ie, I can dynamically alter the built-in string class so that a = "Hello World" b = "hello world" if a == b print "equal!\n" else print "different!\n" end WILL print "equal". In python, there is NO way I can do that. For the purposes of metaprogramming, implementing experimental frameworks, and the like, this amazing dynamic ability of Ruby is extremely appealing. BUT -- if we're talking about large applications, developed by many people and maintained by even more, including all kinds of libraries from diverse sources, and needing to go into production in client sites... well, I don't WANT a language that is QUITE so dynamic, thank you very much. I loathe the very idea of some library unwittingly breaking other unrelated ones that rely on those strings being different -- that's the kind of deep and deeply hidden "channel", between pieces of code that LOOK separate and SHOULD BE separate, that spells death in large-scale programming. By letting any module affect the behavior of any other "covertly", the ability to mutate the semantics of built-in types is just a BAD idea for production application programming, just as it's cool for tinkering.

If I had to use Ruby for such a large application, I would try to rely on coding-style restrictions, lots of tests (to be rerun whenever ANYTHING changes -- even what should be totally unrelated...), and the like, to prohibit use of this language feature. But NOT having the feature in the first place is even better, in my opinion -- just as Python itself would be an even better language for application programming if a certain number of built-ins could be "nailed down", so I KNEW that, eg, len("ciao") is 4 (rather than having to worry subliminally about whether somebody's changed the binding of name 'len' in the builtins module...). I do hope that eventually Python does "nail down" its built-ins.

But the problem's minor, since rebinding built-ins is quite a deprecated as well as a rare practice in Python. In Ruby, it strikes me as major -- just like the too powerful macro facilities of other languages (such as, say, Dylan) present similar risks in my own opinion (I do hope that Python never gets such a powerful macro system, no matter the allure of "letting people define their own domain-specific little languages embedded in the language itself" -- it would, IMHO, impair Python's wonderful usefulness for application programming, by presenting an "attractive nuisance" to the would-be tinkerer who lurks in every programmer's heart...).

alex


Another difference in lambdas between Python and Ruby is demonstrated by Paul Graham's Accumulator Generator problem. Reprinted here:

Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i. Note: (a) that's number, not integer, (b) that's incremented by, not plus.

In Ruby, you can do this:

def foo(n)
  lambda {|i| n += i }
end

In Python, you'd create an object to hold the state of n:

class foo(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

Some folks might prefer the explicit Python approach as being clearer conceptually, even if it's a bit more verbose. You store state like you do for anything else. You just need to wrap your head around the idea of callable objects. But regardless of which approach one prefers aesthetically, it does show one respect in which Ruby lambdas are more powerful constructs than Python's.


I would like to mention Python descriptor API that allows one customize object-to-attribute "communication". It is also noteworthy that, in Python, one is free to implement an alternative protocol via overriding the default given through the default implementation of the __getattribute__ method. Let me give more details about the aforementioned. Descriptors are regular classes with __get__ , __set__ and/or __delete__ methods. When interpreter encounters something like anObj.anAttr , the following is performed:

  • __getattribute__ method of anObj is invoked
  • __getattribute__ retrieves anAttr object from the class dict
  • it checks whether abAttr object has __get__ , __set__ or __delete__ callable objects
  • the context (ie, caller object or class, and value, instead of the latter, if we have setter) is passed to the callable object
  • the result is returned.

As was mentioned, this is the default behavior. One is free to change the protocol by re-implementing __getattribute__ .

This technique is lot more powerful than decorators.


I'm unsure of this, so I add it as an answer first.

Python treats unbound methods as functions

That means you can call a method either like theobject.themethod() or by TheClass.themethod(anobject) .

Edit: Although the difference between methods and functions is small in Python, and non-existant in Python 3, it also doesn't exist in Ruby, simply because Ruby doesn't have functions. When you define functions, you are actually defining methods on Object.

But you still can't take the method of one class and call it as a function, you would have to rebind it to the object you want to call on, which is much more obstuse.


Python has docstrings and ruby doesn't... Or if it doesn't, they are not accessible as easily as in python.

Ps. If im wrong, pretty please, leave an example? I have a workaround that i could monkeypatch into classes quite easily but i'd like to have docstring kinda of a feature in "native way".


Ruby has a line by line loop over input files (the '-n' flag) from the commandline so it can be used like AWK. This Ruby one-liner:

ruby -ne 'END {puts $.}'

will count lines like the AWK one-liner:

awk 'END{print NR}'

Ruby gets feature this through Perl, which took it from AWK as a way of getting sysadmins on board with Perl without having to change the way they do things.


Ruby has embedded documentation:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end

Ruby has sigils and twigils, Python doesn't.

Edit : And one very important thing that I forgot (after all, the previous was just to flame a little bit :-p):

Python has a JIT compiler ( Psyco ), a sightly lower level language for writing faster code ( Pyrex ) and the ability to add inline C++ code ( Weave ).


Syntax is not a minor thing, it has a direct impact on how we think. It also has a direct effect on the rules we create for the systems we use. As an example we have the order of operations because of the way we write mathematical equations or sentences. The standard notation for mathematics allows people to read it more than one way and arrive at different answers given the same equation. If we had used prefix or postfix notation we would have created rules to distinguish what the numbers to be manipulated were rather than only having rules for the order in which to compute values.

The standard notation makes it plain what numbers we are talking about while making the order in which to compute them ambiguous. Prefix and postfix notation make the order in which to compute plain while making the numbers ambiguous. Python would already have multiline lambdas if it were not for the difficulties caused by the syntactic whitespace. (Proposals do exist for pulling this kind of thing off without necessarily adding explicit block delimiters.)

I find it easier to write conditions where I want something to occur if a condition is false much easier to write with the unless statement in Ruby than the semantically equivalent "if-not" construction in Ruby or other languages for example. If most of the languages that people are using today are equal in power, how can the syntax of each language be considered a trivial thing? After specific features like blocks and inheritance mechanisms etc. syntax is the most important part of a language,hardly a superficial thing.

What is superficial are the aesthetic qualities of beauty that we ascribe to syntax. Aesthetics have nothing to do with how our cognition works, syntax does.


You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.

Un esempio:

class Kaka
  puts self
end

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.







ruby