author :Doug Turnbull
translator : Cat under peas @Python cat
original text :https://softwaredoug.com/blog/2021/11/12/ruby-vs-python-for-loop.html
Ruby And Python To a large extent, the difference can be achieved through for
The cycle sees the essence .
Python Have for
sentence . The object told for
How to collaborate , and for
The loop handles the contents returned by the object .
Ruby On the contrary . stay Ruby in ,for
In itself ( adopt each
) Is a method of an object . The caller will for
The loop body is passed to this method .
stay Python In our language habits , The object model is subject to for loop . And in the Ruby in ,for The loop obeys the object model .
in other words , stay Python in , If you want to customize the iterative process , You can let the object tell the interpreter how to iterate :
class Stuff: def __init__(self): self.a_list = [1,2,3,4] self.position = 0 def __next__(self): try: value = self.a_list[self.position] self.position += 1 return value except IndexError: self.position = 0 raise StopIteration def __iter__(self): return self
ad locum ,Stuff Use __next__ and __iter__ The magic method makes itself iteratable ( Become an iteratable object ).
for data in Stuff(): print(data)
However , stay Ruby In the use of , You have to do the opposite . You will for Create a method , It receives code (body body ) To run the .Ruby Put the procedure code in a code block , So they can be used to pass .
then , stay each
In the method , Use yield
Interact with code blocks , Pass the value to the code block to do what you need to do ( For any method , A code block is an implicit parameter ).
If we rewrite the above code , It's going to be like this :
class Stuff def initialize @a_list = [1, 2, 3, 4] end def each for item in @a_list yield item end end end
Use each
To iterate :
Stuff.new().each do |item| puts item end
Not passing data to for loop (Python), Instead, pass the loop code to the data (Ruby).
But the difference is much more than that :
Python Build similar to for Structure , Used for various processing ;Ruby Put data processing work into methods .
first-class Python The code uses list and dictionary parsing to implement map
and filter
, The core of these expressions is for/ The semantics of iteration are the same .
In [2]: [item for item in Stuff()] Out[2]: [1, 2, 3, 4] In [3]: [item for item in Stuff() if item % 2 == 0] Out[3]: [2, 4]
Ruby Then continue to use the method first method , except each
Method , There are also a series of new methods commonly used to deal with collections , As shown below :
class Stuff ... def select out = [] each do |e| # If block returns truthy on e, append to out if yield(e) out << e end end out end def map out = [] # One line block syntax, append output of block processed on e to out each {|e| out << yield(e) } out end
puts Stuff.new().map {|item| item} puts Stuff.new().select{|item| item.even?}
Python say :“ You tell us how to iterate your instance , We will decide how to process your data .” Python There are language based primitives for iteration and processing , If you want to customize the iteration , Just add the correct code to for The loop body ( Or expressions ) in .
Ruby Reversed the script , Give objects deeper customizability . Yes , In some cases , We can add more control flows to the code block . Yes , We can also put each Methods are used to do map. however Ruby Allow objects to implement different map and each( If you will “each” The implementation of is used for “map”, It may be very unsatisfactory , Not even safe ).Ruby Objects in processing their data , There is a better way .
stay Ruby in , Objects control the visibility of functions . And in the Python in , It's grammar that controls .
Authentic Python Have a strong view of data processing .Python say :“ see ,90% Your code fits these ideas well , Just follow it , Just finish the work .” Turn your object into something that can for- Cyclic , Don't bother me any more .
However Ruby say :“ In some important cases , We don't want to give the caller too much power .” therefore Ruby Let objects control how they are processed , And require developers to follow the way objects want to be interacted .Ruby Not so strong in data processing .
Python More like based on C Linguistic “ object-oriented ” Programming extensions . Based on C Of OO in , It's like posix A file descriptor or Win32 Like window handles , Language does not force “ Method ” Bind to the object itself . contrary , Object to method binding is only based on conventions .
Python Think the world can evolve in this process —— It upgrades this way of thinking , Make it safer . Free functions exist (Python Cat note : It should refer to built-in functions , Because it does not depend on any class object , So it is “ The freedom of the ”), And indeed, it is often more recommended than object methods . Objects exist , But in a relatively hesitant way .
Class method receives “self” As its first parameter , Almost Win32 or Posix API Medium C Functions accept handles in the same way . When a function is passed , They are almost regarded as C Function pointer to treat .
Python Consider the procedural paradigm (procedural paradigm) Is the most important , It is the key foundation of everything , Above it is the object-oriented semantic layer .
However ,Ruby But turn it upside down .Ruby Take object-oriented as the basis of the pyramid .Ruby The chaotic process world is contained in the code block , Let objects use these process blocks .
Ruby There is no object destruction in order to follow the procedural basis of the language , It's about adapting procedural code to the world view of the object .Ruby There are real private methods , Unlike Python Private methods of / Parameters , Just out of agreement .
without doubt , When I touch... From the perspective of system programming Python when , It's natural to my perception . Have the ability to write when necessary C The power of language , It evolved , Make that world safer . Maybe that's why it's in the field of system resource intensive numerical computing , Found a place to use .
It is no wonder that Ruby It is suitable for developers to build more smoothly 、 Maybe safer API and DSL.Ruby Programmers are expected to model the domain , Instead of modeling the programming environment , This is for many jobs , Seems to be the right way .