python函数高级用法教程
Python内置了很多有用的函数,我们可以直接调用。要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。
也可以在交互式命令行通过help(abs)查看abs函数的帮助信息
1.2 定义函数定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
如何导入外部的一个定义函数
1.2.1 返回值Python 可以通过调用一个方法返回多个值,但这是一种假象,因为python返回值是一个tuple!在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
1.2.2 可变参数Python函数中,还可以定义可变参数。可变参数就是传入的参数个数是可变的
eg.首先我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
调用calctotal (numbers) ,可以看做是一个参数,这个参数是一个list 或者tuple(元组)
下面修改为可变参数
关键字参数 :
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
定义这样一个关键字参数:
1.2.3 递归函数注意:使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
二.python 的高级特性 2.1 切片看下面一段代码
下面来看切片的一些常用写法
切片的定义:
s = [start :end : step]
注意:步进值为step
当step > 0 时
切片从 start(含start)处开始,到end(不含end)处结束,**从左往右**,每隔(step-1)(索引之间的差仍为step,但相隔的元素是step-1个)个元素进行一次截取。
这时,start 指向的位置应该在end指向的位置的左边,否则返回值为空
当step < 0 时
切片从 start(含start)处开始,到end(不含end)处结束,**从右往左**,每隔(step-1)(索引之间的差仍为step,但相隔的元素是step-1个)个元素进行一次截取。
这时,start 指向的位置应该在end指向的位置的右边,否则返回值为空
2.2 迭代对于给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断
2.3 列表生产式举个例子,要生成list[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):
但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环:
有没有什么简单的方法呢,那当然是使用python的列表生产式,一句代码搞定
双层循环
2.4 生成器通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。绝大多数元素占用的空间浪费严重。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:使用for循环可以遍历一个generator,因为generator也是可迭代对象:
generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
试着使用生成器输出杨辉三角的前10行
注:普通函数和generator生成器的区别:
1.普通函数调用直接返回结果,generator函数的调用,返回一个generator对象;(调用generator时可以先创建一个对象,再用next()方法不断获得下一个返回值,但实际中通常用for循环实现)
2.generator在执行过程中,遇到yield就中断,下次又继续执行
2.5 迭代器可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用isinstance()判断一个对象是否是Iterable对象。
凡是可作用于for循环的对象都是Iterable类型;凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。Python的for循环本质上就是通过不断调用next()函数实现的
三.高阶函数 3.1 map和reduce函数3.1.1从参数方面:
map()函数:
map()包含两个参数,第一个是参数是一个函数,第二个是序列(列表或元组)。其中,函数(即map的第一个参数位置的函数)可以接收一个或多个参数。
reduce()函数:
reduce() 第一个参数是函数,第二个是 序列(列表或元组)。但是,其函数必须接收两个参数。
3.1.2从对传进去的数值作用来讲:
map()是将传入的函数依次作用到序列的每个元素,每个元素都是独自被函数“作用”一次;
reduce()是将传人的函数作用在序列的第一个元素得到结果后,把这个结果继续与下一个元素作用(累积计算),最终结果是所有的元素相互作用的结果。
3.2 filterPython内建的filter()函数用于过滤序列,看一个打印1000以内素数的选择器
3.3 sorted 函数3.3.1. sorted()函数就可以对list进行排序
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序
3.4 装饰器 3.5 偏函数假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:
四.模块在Python中,一个.py文件就称之为一个模块(Module),使用模块的最大好处就是提高了代码的可维护性,一个模块编写完毕,可以在其他地方引用,尽量不用命名与python内置模块同名的模块,引入包来避免自定义同名的模块,引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。
请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。
4.1 使用模块使用 import 文件名 导入模块 ,可以调用模块内的方法和变量
4.2 作用域在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。
正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;
eg : hello.py
calc.py
这样我们调用hello.py 中的计算两数乘积的函数myCalc 而不需要关心它的内部实现,这也是一种非常有用的代码封装和抽象的方法
4.3 安装第三方模块安装第三方模块,是通过包管理工具pip完成的。 第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Pillow的名称叫Pillow(强大的图片处理库),因此,安装Pillow的命令就是:
pip install Pillow