我试图通过翻译Jamis Buck的Mazes for Programmers一书中的代码来自学Python。它是一本很棒的书,但是它是用Ruby编写的,而且我很难理解一些Ruby代码。
为了解这个问题,我已经包含了代码库的简化版本
cell.rb
class Cell
attr_reader : row, :column
def initialize(row, column)
@row, @column = row, column
end
grid.rb
require 'cell'
class Grid
attr_reader :rows, :columns
def initialize(rows, columns)
@rows = rows
@columns = columns
@grid = prepare_grid
end
def prepare_grid
Array.new(rows) do |row|
Array.new(columns) do |column|
Cell.new(row, column)
end
end
end
到目前为止一切顺利。以上所有内容都很容易理解并转换为Python。然后有以下两个函数作为Grid类的一部分。
def each_row
@grid.each do |row|
yield row
end
end
def each_cell
each_row do |row|
row.each do |cell|
yield cell if cell
end
end
end
这里的最后两个功能实际上是做什么的?我发现了类似here的东西,这让我觉得Python版本需要接受一个可选的lambda变量,测试看它是不是null,如果它不是'然后运行与变量关联的代码。问题是我知道这些函数的意图是成为迭代器,我不认为添加lambda会有所帮助。
在StackOverflow上已经有一个类似的问题here让我觉得答案是微不足道的,但是我不太了解Ruby能够直接得到答案或者问Google是否正确的问题。
答案 0 :(得分:4)
然后有以下两个函数作为Grid类的一部分。
这些不是功能。它们是方法。
def each_row @grid.each do |row| yield row end end def each_cell each_row do |row| row.each do |cell| yield cell if cell end end end
这里的最后两个功能实际上是做什么的?
each_row
方法将块作为参数,并将连续yield
@grid
数组的所有元素。 @grid
结构为数组数组,表示单元格行。换句话说,each_row
将连续yield
网格的每一行,即它是行的迭代器方法。
each_cell
方法将块作为参数,并将连续yield
网格@grid
数组中行数组的所有元素。换句话说,each_cell
将连续yield
网格的每个单元格(如果存在),即它是单元格的迭代器方法。
Python的字面翻译将是这样的(未经测试):
def each_row(self, f):
self.grid.each(lambda row: f(row))
def each_cell(self, f):
self.each_row(lambda row: lambda cell: if cell: f(cell))
但是,以这种方式将代码从一种语言翻译成另一种语言是没有意义的。在Python中使用lambdas迭代是非惯用的。 Python使用迭代器进行迭代。因此,不是使用each_row
和each_cell
迭代器方法,而是使用row_iterator
和cell_iterator
getter来返回行和单元格的迭代器对象,这样就可以了做类似的事情:
for cell in grid.cell_iterator
而不是
grid.each_cell(lambda cell: …)
这样的事情(也是未经测试的):
def row_iterator(self):
for row in self.grid: yield row
def cell_iterator(self):
for row in self.row_iterator:
for cell in row:
if cell: yield cell
当你将代码从一种语言“翻译”到另一种语言时,你不能只是逐行,逐个语句,逐个表达式,逐个子程序,逐个类地翻译它,您需要从头开始重新设计它,使用社区的模式,实践和习惯用语以及语言及其核心和标准库中的类型,类,子例程,模块等。
否则,您可以使用编译器。编译器实际上被定义为“将程序从一种语言翻译成另一种语言的程序”。如果这就是您想要做的,请使用编译器。但是,如果您希望翻译后的代码具有可读性,可理解性,可维护性和惯用性,则只能由人工完成。