函数
1、定义:
def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。
def 是固定的,不能变,必须是连续的def三个字母,不能分开。。。它们要相亲相爱的在一起。
空格 为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。
函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能
括号:是必须加的,先别问为啥要有括号,总之加上括号就对了!
2、注释:
每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
3、函数的调用:
就是 函数名() 要记得加上括号,好么好么好么。
4、函数的名的规则:
必须的由字母下划线数字组成。
不能有和数字开头
变量名有一定的意义,能说明一定的功能。
5、函数的返回值:
可以但会任意值,任意类型。
一、若果有返回值:必须要用变量接收才有效果。
二、函数当不写return的时候,一个函数默认的函数返回值‘None’
三、函数中只写return不写返回值,同样返回‘None’
总结:一个函数的返回值为Noen的三种情况
一、不写返回值
二、只写一个人return
三、返回return,none(几乎不用)
6、return的作用
一、 如果在函数体中,在结尾不写return是不行的,因为return在函数中还有结束函数体的作用。
总结:结束函数的执行
返回一个值
二、返回值不为None的三种情况。
1、return XXX 返回一个值。(一个变量)
2、return a,b,c 返回多个值(多个变量用 , 区分,以元祖的方式组装)
三、返回值接收的:
1、可以用一个变量接收。
2、也可以用多个变量接收,返回几个值就用几个变量接收。
7、参数
实参:函数调用的时候,传入的数值。
形参:是函数定义的时候定义的参数名。
位置参数
站在实参角度
1.按照位置传值
def mymax(x,y): #此时x=10,y=20 the_max = x if x > y else y return the_max ma = mymax(10,20) print(ma)
def mymax(x,y): #此时x=10,y=20 the_max = x if x > y else y return the_max ma = mymax(10,20) print(ma)
2.按照关键字传值
def mymax(x,y): #此时x = 20,y = 10 print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) print(ma)
def mymax(x,y): #此时x = 20,y = 10 print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) print(ma)
3.位置、关键字形式混着用
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max ma = mymax(10,y = 20) print(ma)
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max ma = mymax(10,y = 20) print(ma)
默认参数
1.正常使用
使用方法
为什么要有默认参数:将变化比较小的值设置成默认参数
2.默认参数的定义
def stu_info(name,sex = "male"): """打印学生信息函数,由于班中大部分学生都是男生, 所以设置默认参数sex的默认值为'male' """ print(name,sex) stu_info('alex') stu_info('eva','female')
3.参数陷阱:默认参数是一个可变数据类型
def defult_param(a,l = []): l.append(a) print(l) defult_param('alex') defult_param('egon')
动态参数
按位置传值多余的参数都由args统一接收,保存成一个元组的形式
def mysum(*args): the_sum = 0 for i in args: the_sum+=i return the_sum the_sum = mysum(1,2,3,4) print(the_sum)
def stu_info(**kwargs): print(kwargs) print(kwargs['name'],kwargs['sex']) stu_info(name = 'alex',sex = 'male')
本章小结
面向过程编程的问题:代码冗余、可读性差、可扩展性差(不易修改)
定义函数的规则:
1.定义:def 关键词开头,空格之后接函数名称和圆括号()。
2.参数:圆括号用来接收参数。若传入多个参数,参数之间用逗号分割。
参数可以定义多个,也可以不定义。
参数有很多种,如果涉及到多种参数的定义,应始终遵循位置参数、*args、默认参数、**kwargs顺序定义。
如上述定义过程中某参数类型缺省,其他参数依旧遵循上述排序
3.注释:函数的第一行语句应该添加注释。
4.函数体:函数内容以冒号起始,并且缩进。
5.返回值:return [表达式] 结束函数。不带表达式的return相当于返回 None
def 函数名(参数1,参数2,*args,默认参数,**kwargs):
"""注释:函数功能和参数说明"""
函数体
……
return 返回值
调用函数的规则:
1.函数名() 函数名后面+圆括号就是函数的调用。 2.参数: 圆括号用来接收参数。 若传入多个参数: 应按先位置传值,再按关键字传值 具体的传入顺序应按照函数定义的参数情况而定 3.返回值 如果函数有返回值,还应该定义“变量”接收返回值 如果返回值有多个,也可以用多个变量来接收,变量数应和返回值数目一致 无返回值的情况: 函数名() 有返回值的情况: 变量 = 函数名() 多个变量接收多返回值: 变量1,变量2,... = 函数名()
8、函数的作用域和名称空间
代码在运行伊始:创建的存储“变量名与值的关系”的空间叫做,
局部命名空间:在函数的运行中开辟的临时的空间
命名空间一共分为三种:
内置命名空间:python解释器自带的名字,python解释器启动就会生效。
全局命名空间:文件级别定义的名字都会存放在全局名称空间,执行python文件就会产生。
局部命名空间:定义在函数内部的名字,局部名称空间只有调用函数的时候就会生效,函数调用结束则失效
三者的加载顺序:内置命名空间-------》 全局命名空间 -------------》 局部命名空间
三者的取值顺序:局部命名空间------------>全局命名空间 --------------》 内置命名空间
9.作用域
全局作用域:
内置名称空间与全局名称空间的名字,属于全局的范围。在整个文件的任意位置都能引用。(全局有效)
局部作用域:
局部名称空间的名字属于局部范围,只有函数内部可以被引用,(局部有效)
内置命名空间, 全局命名空间-----------------全局作用范围
局部命名空间---------------------------------------------局部范围
10、闭包
作用:就是能够应用外部的变量,并且还能保证外部的变量被控制在一个局部作用域中。
闭包函淑满足的要求:
1、必须是内部函数
2、包含对外部作用域而非全局作用域的引用
特点:自带作用域,延迟计算。
闭:封闭在内部的函数。
包:内部函数被返回出来的时候。外面还包含着一层作用域。
def func(): name = 'eva' def inner(): print(name) return inner f = func() f() 复制代码
11、装饰器
本质:就是闭包函数
功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能。
设计模式:
原则:开放封闭原则
1、对扩展是开放的:我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2、独修改是封闭的:就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器的固定格式:
def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner
带参数的装饰器
def outer(flag): def timer(func): def inner(*args,**kwargs): if flag: print('''执行函数之前要做的''') re = func(*args,**kwargs) if flag: print('''执行函数之后要做的''') return re return inner return timer @outer(False) def func(): print(111) func()
多个装饰器装饰同一个函数:
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()