七、函数

一、函数的好处

1、组织结构清晰,可读性强

2、代码简洁

3、管理维护的难度小,有扩展性

二、函数的定义和调用

具备某一个功能的工具就是程序中的函数,事先准备工具的过程就函数的定义,拿来就用叫函数的调用

函数的使用必须遵循:先定义,再调用。没有定义函数而直接调用,就相当于在引用一个不存在的变量名

函数定义的语法:

def 函数名(参数1,参数2,……)

    代码块

     return 值

函数名是用来调用函数的,函数名必须反映出函数的功能

定义函数的类型:

1、有参数函数,参数是函数代码接收外部传入值的。函数定义有参,调用函数时也必须传入参数

2、无参数函数,当函数体的代码逻辑不需要函数的调用参数。函数定义无参,调用函数时也必须传入参数

3、空函数,函数体为pass

调用函数:函数名加小括号就是在调用函数

三、函数的执行顺序:

定义阶段:只检测语法,不执行函数体代码

调用阶段:根据函数名找到函数的内存地址,然后执行函数体代码

四、函数的返回值

函数体代码运行完毕后,需要有一个返回结果。

返回值的值没有类型限制

return是函数结束的标志,一个函数里面可以有多个return,但执行一次函数就立即结束,并把return后的值返回给调用者

五、函数的参数

1、形参与实参

形参:形式参数。指的是在定义函数时,括号内定义的参数。形参其实就是变量名

实参:实际参数。指的是在调用函数时,括号内传入的值。实参其实就是变量值

实参值(变量的值)与形参(变量名)的绑定关系只在函数调用时才会生效/绑定,在函数调用结束后立刻解除绑定

2、位置参数

位置即顺序,位置参数指的是按照从左到右的顺序依次定义的参数

位置形参:

在定义函数时,按照位置定义的形参,称为位置形参

特性:位置实参会与形参一一对应

位置实参:

在定义函数时,按照位置定义的实参,称为位置实参

特性:位置实参会与形参一一对应

3、关键字参数

在调用函数时,按照key=value的形式定义的实参,称为关键字参数

相当于指名道姓的为形参传值,意味着即便是不按照顺序定义,仍然能为指定的参数传值

在调用函数时,位置实参与关键字实参可以混合使用,但必须

1)、必须遵循形参的规则

2)、不能为同一个形参重复传值

3)、位置实参必须放在关键字实参的前面

4、默认参数

在定义阶段,已经为某个形参赋值,那么该形参就称为默认参数。

定义阶段已经有值,意味着调用阶段可以不传值

位置形参必须在默认参数的前面

默认参数的值只在定义阶段赋值一次,也就是说默认参数的值在定义阶段就固定了

默认参数的值应该设置为不可变类型(数字、字符串、元组)

5、可变参数

可变参数指的是参数的长度可变(参数的个数不固定)

实参有按位置定义的实参和按关键字定义的实参,所以可变实参指的是按照这两种形式定义的实参个数可以不固定

然而实参终究是要给形参传值的,所以这两种形式带可变,形参对应有两种解决方案来完整的存放它们:*args和**kwargs

*args会将溢出的关键字实参全部接收,然后保存成字典的形式,赋值给kwargs

一旦碰到实参加*和**的,就把该实参的值打散

组合使用的时候,*必须在**的前面

6、命名关键字参数

格式:在*后面定义的参数都是命名关键字参数

特点:约束函数的调用者必须按照key=value的形式传值

约束函数的调用者必须用我们指定的key名

六、函数嵌套

函数的嵌套调用:在函数内又调用了其他的函数

函数的嵌套定义:在函数内又定义了其他的函数

七、名称空间与作用域

1、名称空间是存放名字与值绑定关系的地方

分为:

1)、内置名称空间:Python解释器自带的名字,在解释器启动时就生效,关闭则失效

2)、全局名称空间:文件级别的名字(顶头、无缩进的名字),在执行文件的时候生效,在文件结束或文件执行期间删除则失效

3)、局部名称空间:函数内的名字,函数的参数及函数内的名字,在函数调用时临时生效,函数结束则失效

加载名称空间的顺序:内置 --> 全局 --> 局部

查找名称空间的顺序:局部 --> 全局 --> 内置

2、作用域

分为:

全局作用域:包含内置名称空间和全局名称空间,在任何位置都可以访问到

局部作用域:包含局部名称空间,只能在函数内使用

3、函数对象

函数是Python中的第一类对象,指的是函数可以

可以被引用

可以当作参数传入

可以当作函数的返回值

可以当作容器类型的元素

八、闭包函数

定义在函数内部的函数,并且该函数包含对外部函数作用域(不是全局作用域)中名字的引用,该函数就称为闭包函数

通常将闭包函数用return返回,然后就可以在任意位置使用

作用域关系在函数定义阶段就规定死了,与调用关系无关

为函数体传值的两种方式:
1、直接为该函数添加相对应的参数

2、以闭包函数的形式传值

九、装饰器

软件一旦上线,就应该遵循开放封闭的原则,即对修改源代码是封闭的,对功能的扩展是开放的,也就是说我们必须找到一种解决方案:能够在不修改一个功能源代码及调用方式的前提下,为其加上新功能

原则:1、不修改源代码;2、不修改调用方式

装饰器就是在不修改被装饰对象源代码与调用方式前提下,为被装饰对象添加新功能

装饰器与被装饰对象均是可以任意调用的对象,可以是函数

装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问。

装饰器基本形式模板

def outter(func):

    def wrapper(*args,**kwargs):

        res = func(*args,**kwgars)

        return res

    return wrapper

语法糖:@outter

叠加多个装饰器:

@

@

上面的@ = 下面的@ + 装饰器

十、迭代器

迭代是一个重复的过程,并且每次重复都是基于上次结果来的

可迭代的对象:在Python中,但凡内置有__iter__方法的对象,都是可迭代的对象

迭代器对象:迭代器是迭代取值的工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象,再用__next__方法取值

字符串、列表、元组、字典、集合、文件是可迭代对象,数字和函数不是。文件即是可迭代对象,也是迭代器对象

迭代器特点:

1、内置有__next__方法,执行该方法拿到的返回值就是迭代器的对象

2、内置有__iter__方法,执行该方法会拿到迭代器本身

优点:
1、提供了一种不依赖索引的取值方式

2、迭代器更加节省内存

缺点:

取值麻烦,只能一个一个取,而且只能往后取,并且是一次性的,无法用len获取长度

for循环称之为迭代器循环,in后跟的必须是可迭代的对象

for循环的原理:

1、先判断对象是否是可迭代对象,不是的话直接报错,抛出TypeError异常;是的话,调用__iter__方法,返回一个迭代器

2、不断的调用迭代器的__next__方法,每次按序返回迭代器中的一个值

3、迭代到最后,没有更多元素了,就抛出StopIteration,这个异常python自己会处理,不会暴露给开发者

十一、生成器

函数内包含有yield关键字,再调用函数,就不会执行函数体代码。拿到的返回值就是一个生成器对象

生成器本质上就是迭代器,生成器的用法和迭代器一样

1、__iter__,拿到迭代器

2、__next__,拿到该方法的返回值,赋值

3、周而复始,直到函数内不再有yield,即取值完毕

4、for会检测到异常,结束循环

优点:

1、提供了自定义迭代器的方法

2、yield可以像return一样用于返回值,区别是return只能返回一次,而yield可以返回多次(yield可以保存函数执行的状态)

yield的表达式

1、初始化一次,让函数停在yield的位置

.__next__()

2、.send()

.send()的功能:1、给yield传值;2、与__next__()的效果一致

十二、三元表达式

基本语法:

x if x > y else y

仅用于:条件成立返回一个值,条件不成立返回一个值

十三、函数的递归

在函数的调用过程中,又直接或间接的调用了函数本身

直接调用:

def func():
    print('')

    func()

func()

间接调用:
def func1():
    print('')

    func()

def func():
    print('')

    func1()

func1()

递归分为两个阶段:

1、回溯:一定要在满足某种条件中结束回溯,否则会无限递归

2、递推

总结:

1、递归一样要有一个明确的结束条件

2、每进入下一次递归,问题的规模都应该减少

3、在Python中没有尾递归优化

了解:Python中默认递归层级为1000,可修改

十四、匿名函数

基本语法:

lambda x,y:x+y

特点:

1、给匿名函数赋值给一个名字是没有意义的

2、匿名函数的参数规则、作用域关系和有名函数是一样的

3、函数体是冒号右边的部分,通常是一个表达式,必须要又一个返回值

4、匿名函数不会单独使用

5、自带return

十五、列表生成式

l = ['a' for i in range(10) if i > 5]

十六、生成器表达式

l = ('a' for i in range(10) if i > 5)

十七、内置函数

max()
min()
sorted()   排序
map()   映射
reduce()   合并
filter()   过滤

abs()   取绝对值
all()   列表中布尔值全部为真,结果为真
any()    布尔值只要一个为真,结果为真
bytes()    把任何类型转成bytes类型
callable()   判断一个对象是否可调用
chr()
ord()
eval()   将字符串内的表达式拿出来运行一下,并拿到该表达式的执行结果
globals()   查看全局作用域的名字与值的绑定关系
locals()   查看局部作用域的名字与值的绑定关系
hash()      判断类型是否是不可变类型
zip()   拉链

十八、面向过程编程

先干什么,再干什么

优点:复杂的问题流程化,进而简单化

原文地址:https://www.cnblogs.com/Python1/p/8808563.html