python学习笔记(三)
函数式编程:
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python内建了map()和reduce()函数。
map():函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。举例:有一个函数f(x)=x^2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:
>>>map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce():把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> def fn(x, y): ...
return x * 10 + y ...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
filter():和map()类似,也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
在一个list中,删掉偶数,只保留奇数,可以这么写:
def is_odd(n):
return n % 2 == 1
filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]) # 结果: [1, 5, 9, 15]
sorted():该函数可以对list进行排序,sorted([36, 5, 12, 9, 21])。它也是一个高阶函数,可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,就可以自定义一个reversed_cmp函数:
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
传入自定义的比较函数reversed_cmp,就可以实现倒序排序:
>>> sorted([36, 5, 12, 9, 21], reversed_cmp) [36, 21, 12, 9, 5]
面向对象编程
类:
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
#Student类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。 __init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创#建的实例本身。有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。
类中定义的函数和其他函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,仍然可以用默认参数、可变参数和关键字参数。
外部代码还是可以自由地修改一个实例的name、score属性
>>> bart = Student('Bart Simpson', 98)
>>> bart.score
98
>>> bart.score = 59
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__。self.__name = name,self.__score = score
在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,不能用__name__、__score__这样的变量名。
多态:
当我们定义一个class的时候,就相当于定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样:
判断一个变量是否是某个类型可以用isinstance()判断:
>>> isinstance(a, list)
true 或 false
在调用类实例方法的时候,变量视作父类类型,这样,所有子类类型都可以正常被接收。