我正在尝试与Python结合使用一些mapreduce。
现在我从我正在做的教程中运行以下代码。
from mrjob.job import MRJob
class SpendByCustomer(MRJob):
def mapper(self, _, line):
(customerID, itemID, orderAmount) = line.split(',')
yield customerID, float(orderAmount)
def reducer(self, customerID, orders):
yield customerID, sum(orders)
if __name__ == '__main__':
SpendByCustomer.run()
应该执行以下操作。
当我点击!python SpendByCustomers.py customer-orders.xls > test.txt
时
它应该在.xls
文件中读取,映射并减少它并将输出写入test.txt
。
一切正常,我大多理解它。不过,我真的希望得到更多有关以下内容的见解:
在
def mapper(self, _, line):
_
在这做什么?
在
if __name__ == '__main__':
SpendByCustomer.run()
这个功能到底在做什么?
答案 0 :(得分:2)
在Python中,字母,数字和下划线可用于变量名称。 (变量名不能以数字开头。)下划线是常用的变量名,用于不使用的值。例如,如果我想打印"你好" 5次,我可以做到以下几点:
for _ in range(5):
print("hello")
在那个例子中,_
并没有真正做任何事情;它就在那里,因为我们必须在那里放置一些变量名,但使用 变量名是向其他程序员发出的消息,查看代码不会使用该变量。对于函数,这是因为mapper
方法通常使用三个参数调用,但在mapper
方法中,该参数未使用。至于第二个问题,SpendByCustomer.run()
是mrjob.job.MRJob
类中定义的方法。正如您可能从其名称中猜到的那样,它运行MapReduce作业。它使用您的mapper()
方法和reducer()
方法来执行此操作。
答案 1 :(得分:0)
在
def mapper(self, _, line):
_
在这做什么?
MRJob.mapper
的方法签名为MRJob.mapper(key, value)
如果在派生类中重新定义它(就像那样),则必须保留兼容的签名,因此必须接受两个参数。将使用某个键作为第一个参数调用您的函数,将某个值作为第二个参数调用。文档指出“如果你不乱用协议”,你将被调用的密钥将是None
,所以它并不特别有趣。因此,重新定义方法对它没有任何作用。
在Python中,通常使用名称_
作为签名中必须具有的参数以保持与接口兼容。从技术上讲,这个参数名称并没有什么特别之处。它只是一个单字符名称,使用标识符允许的字符之一。它的选择主要是因为它的视觉外观(看起来有点像未填写的字段)告诉人类读者你的代码:我在这里传递了一个值,但我不在乎它是什么(并且不会在它中使用它我的实施)。
在
if __name__ == '__main__': SpendByCustomer.run()
这个功能到底在做什么?
对于if __name__ == '__main__':
部分,请参阅What does if __name__ == "__main__": do?
对于.run()
部分,请参阅MRJob documentation。