第三章 过程大于结果
3.1 懒人炒菜机
1.函数是什么
·函数定义了两组数字间的对应关系。
·对于程序员来说,函数就是把一些指令封装在一起,形成一套组合。一旦定义好了函数,我们就可以通过对函数的调用,来启动这套组合。
2.定义函数
·制作函数的过程又称之为定义函数(define function)【def】
·最先出现def,这个def通知Python“这里要定义函数了”,关键字def后面跟着函数的名称,在函数名的后面还有一个括号,表示函数有哪些参数,即a和b,参数可以有多个,也可以完全没有。(根据语法规定,即使没有输入数据,函数后面的括号也要保留)
·由于函数定义中的参数是一个形式代表,并非真正的数据,所以又称为形参(Parameter)。
·return用于说明函数的返回值,即函数的输出数据。(还起到了中止函数和制定返回值的功能)如果没有return,或者return后面没有返回值时,则函数将返回None(表示什么都没有)。
3.调用函数
·在函数调用时出现的参数称为实参(argument)。
4.函数文档
·我们可以用内置函数help()来找到某个函数的说明文档。以help(max)为例:
·对于自定义的函数,需要自己加上注释,在参数和返回值上要尽量写得详细。
3.2 参数传递
1.基本传参
·把数据用参数的形式输入到函数,被称为参数传递。
·如果只有一个参数,只需把函数调用时输入的唯一数据对应为参数就可以了;如果有多个参数,那么在调用函数时,Python会根据位置来确认数据对应哪个函数。
·关键字(Keyword)传参,如果在调用时使用关键字传参,那么就不用遵守位置的对应关系。
·位置传参与关键字传参可以混合使用,即一部分的参数传递根据位置,另一部分根据参数名。(注意:在调用函数时,所有的位置参数都要出现在关键字参数之前,否则程序将会报错)
·如果我们在调用时不提供这些形参的具体数据,那么它们将采用定义时的默认值。
2.包裹传参
·用于我们并不知道参数的个数时。
·包裹位置传参:所有的数据都根据先后顺序,收集到一个元组。在函数内部,通过元组来读取传入的数据。
·在定义package_position()时要在元组名all arguments前加*号。
.包裹关键字传参:把传入的数据收集为一个词典,当函数调用时,所有参数会收集到数据容器里,把数据传递给函数使用。
·为了提醒参数all-arguments是包裹关键字传递所用的字典,因此在all_arguments前加**号。
·包裹传参和基本传参混合使用,其出现顺序:位置👉关键字👉包裹位置👉包裹关键字
3.解包裹
·除了用于函数定义,*和**还可用于函数调用。用于实现“解包裹”,解包裹允许我们把一个数据容器传递给函数,再自动地分解为各个参数。(包裹传参与解包裹并不是相反操作,而是两个相对独立的功能。)
·元组解包裹:在args前加上*号,用来提醒Python ,把元组拆成单个元素,每一个元素对应函数的一个位置参数。
·词典解包裹:在args前加上**号,在传递词典args时,让词典的每个键值作为一个关键字传递给函数unpackage()
·解包裹在调用函数时,几种参数的传递也可以混合,顺序为:位置👉关键字👉位置解包裹👉关键字解包裹
3.3 递归
1.高斯求和与数学归纳法
递归:函数调用其自身的操作。
2.函数栈
·程序中的递归需要用到栈(Stack)这一数据结构。数据结构即计算机存储数据的组织方式。(栈可以有序地存储数据)
·栈最显著的特征是:后进先出(LIFO,Last IN, First Out)
·栈的每一个元素称为一个帧(frame),栈只支持两个操作:pop和push。用弹出(pop)操作来取出栈顶元素,用推入(push)操作将一个新的元素存入栈顶。
3.变量的作用域
·Python寻找变量的范围不止是前帧,它还会寻找函数外部,也就是Python的主程序中定义了的变量。
·当主程序中已经有了一个变量,函数调用内部可以通过赋值的方式创建了一个同名变量。函数会优先使用自己函数帧中的变量。
·且函数内部使用的是自己内部的变量,所以函数内部对变量的操作不会影响到外部变量。(特例:对于数据容器,函数内部的更改会影响到外部)
3.4 引入那把宝剑
1.引入模块
·在Python中,一个.py文件就构成了一个模块。
·通过模块,你可以调用其他文件中的函数。引入(import)模块,就是为了在新的程序中重复利用已有的Python程序。
2.搜索路径
·在引入模块时,把库文件和应用文件放在了同一文件夹下,当在该文件夹下运行程序时,Python会自动在当前文件夹搜索它想要引入的模块。
·标准库是Python官方提供的库,Python会自动搜索标准库所在的路径。
3.5 异常处理
1.恼人的bug
·语法错误
·运行时错误:只有在运行时,编译器才会发现的错误。
·语义错误:编译器认为你的程序没有问题,可以正常运行。但当检查程序时,却发现程序并非你想做的。
2.Debug
·Debug:修改程序缺陷的过程。
3.异常处理
·对于运行时有可能产生的错误,我们可以提前在程序中做处理。
·需要异常处理的程序包裹在try结构中。
·except说明了当特定错误发生时,程序应该如何应对。
·如果没有发生错误,那么try部分正常运行,except部分被跳过。
·如果无法将异常交给合适的对象,那么异常将继续向上层抛出。