@
Eyon 我觉得你可能有一些过程式编程的底子,而这里讨论的sort方法则有函数式编程的意味,所以给你造成了一些困扰,下面我试着解释一下。
python本身包含深广,除了显见的过程式和面向对象思想以外,Guido也借鉴了一些他认为的函数式编程里面好的思想,与这里的问题相关的也是比较重要的一个就是:函数在python里面是first class的,和其他的变量啦、对象啦一样,是一等公民,当然这术语你可以不必理会,只需要知道对于函数f,你可以f()调用,可以g=f赋值,也可以把f当成是参数传递给其他函数,甚至可以把f当成一个函数的返回值返回出来。
下面回到问题本身,list的sort方法可以接收一个函数作为参数,上面的lst.sort(key=get_age)就是把get_age这个函数作为参数传递进sort中去了。
而且lz你的理解是正确的,函数只有被调用之后才有意义,只是这里的调用不是显式进行的,而是由系统帮你完成的。至于是如何完成的,下面可能要绕一个弯子。
sort这个函数稍微复杂一些,我想换一个类似但简单一些的例子,也就是python的另一个内置函数map,如果你能理解map,sort就不成问题了,而且在实战中map的用途也更为广泛。map的官方解释在此https://
docs.python.org/2/library/functions.html#map ,其实已经介绍的很详细了,但我知道一开始还是很难接受,没事,接着看。map的函数签名是map(function, iterable),他的第一个参数是一个函数,第二个参数是一个可迭代对象,典型的例子就是列表,再看map的返回值,比如我调用:
map(f, [item1, item2, item3])
将返回:
[f(item1), f(item2), f(item3)]
那lz你会说,在哪儿调用的呢?当然在map函数的实现中了,下面可以写一个乞丐版的map实现:
def map(func, iterable):
____result = []
____for item in iterable:
________result.append(func(item))
____return result
python的标准库实现要复杂的多,但本质上就是这样。上面的map实现,就是lz更加熟悉的过程式编程了,而直接调用map(f, iters)则有函数式编程的意味,注意两者的区别:前者关注的是如何完成这件事,后者关注的是干了什么。
那么为什么要用函数式编程呢?因为它更短更易读,所以出错的机会少。lz可能会说,明明是for循环更易读啊,那只是你看的多习惯了而已。近年来的高级语言有一个趋势,就是试图消除for循环,而用诸如map这样的高阶函数来取代。lz在学习python的过程中势必有一天要回过头去,将你以前的代码用高阶函数重写,那时你的技艺也会提升一个等级。
好像扯远了,我们回到sort上来。这里的sort是lst的一个方法,如果lz你知道类怎么写的话就知道在列表类的定义中,sort方法默认的第一个参数是self,也就是lst自己,所以lst.sort(key=f)本质上就是sort(lst, key=f),是不是和上面的map很像,在背后的实现中当然也有类似map的将f分别作用于lst的每个元素,并得到一个返回值,然后根据返回值进行排序,再将排序好的列表返回出来,具体的实现就不写了。