python-函数
将重复的代码,封装到函数,只要使用直接找函数。
函数可以增强代码的模块化和提高代码的重复利用率。
1、格式:
def 函数名([参数,参数]):
函数体(重复的代码)
注意:
- 必须使用关键字def;
- 函数体注意缩进;
- 函数名()绑定。
2、可变参数:
def f(*args):
sum = 0
if len(args) > 0:
for i in args:
sum += i
print(sum)
else:
print(sum)
注意: 可变参数必须放在后面
重点1: 关键字参数 key=value
def f(a,b=10,c=4):
result = a+b
print(result)
f(1,5) 表示给b赋值成功,即a=1,b=5,c=4
f(2,c=6) 表示给c赋值而不是给b赋值,即a=2,b=10,c=4
重点2:
- 定义函数的时候,前面加“**”表示装包
- 调用函数的时候,前面加“**”表示拆包
重点3:
def f(a,b,*c,**d):
print(a,b,c,d)
没有关键字:
f(1,2)
>>> 1 2 () {}
f(1,2,3,4)
>>> 1 2 (3,4) {}
有关键字:
f(1,2,x=100,y=200)
>>> 1 2 () {'x':100,'y':200}
3、return返回值
return返回值:将函数中运算的结果通过return关键字“扔”出来
重点:
- return后面可以是一个参数,需要赋值。
x = add(1,2)
- return后面也可以是多个参数,如果是多个参数则底层会将多个参数先放在一个元组中,将元组作为整体返回
x = add(1,2,3)
>>> x ----> (1,2,3)
- 接收的时候也可以是多个。
return 'hello','world'
x,y = ('hello','world')
>>> x='hello' y='world'
4、全局变量
不修改全局变量,只是获取打印。但是如果要发生修改全局变量,则需要在函数内部声明:global+变量名
重点:
- 如果全局变量不可变,在函数中修改时需要添加global关键字。
- 如果全局变量是可变的,在函数中修改时不需要添加global。
5、内部函数
特点:
- 可以访问外部函数的变量
- 可以修改外部函数的可变类型的变量,比如list
- 内部函数修改全局的不可变变量时,需要再内部函数声明:global变量名;
内部函数修改外部函数的不可变变量时,需要在内部函数中声明:nonlocal变量名 - locals()查看本地变量有哪些,以字典的形式输出
globals()查看全局变量有哪些,以字典的形式输出(注意里面会有一些系统的键值对)
6、闭包
在函数中提出的概念。
1、条件:
- 外部函数中定义了内部函数
- 外部函数是有返回值
- 返回的值是:内部函数名
- 内部函数引用了外部函数的变量
2、格式
def 外部函数():
......
def 内部函数():
......
return 内部函数
-
举例
a = 100 def inner_func(): b = 99 print(a,b) return inner_func ```
3、应用
保存返回闭包是的状态(外层函数变量)
- 举例:计数器
def generate_count(): container=0 def add_one(): nonlocal container container+=1 print('当前是第{}次访问'.format(container)) return add_one
4、缺点
- 作用域没有那么直观
- 因为变量不会被垃圾回收所以有一定的内存占用问题。
5、作用:
- 可以使用同级的作用域
- 读取其他元素的内部变量
- 延长作用域
6、总结
- 闭包拟优化了变量,原来需要类对象完成的工作,闭包也可以完成
- 由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存
- 闭包的好处,使代码变得简洁,便于阅读代码
- 闭包的理解装饰器的基础
7、装饰器
判断用户的登录状态
特点:
- 函数A是作为参数出现的(函数B就接收函数A作为参数)
- 要有闭包的特点
- 内层函数
- 内层函数引用外层函数
- 反出内层函数
- 函数作为外层函数的参数
举例:
def decorate(func):
a = '完成了'
def wrapper():
func()
print('------>刷漆')
print('------>铺地板')
print('------>装门')
print(a)
return wrapper
#使用装饰器
@decorate
def house():
print('我是毛坯房')
house()
评价
- house被装饰函数,
- 将被装饰函数作为参数传给装饰器decorate
- 执行decorate函数
万能装饰器
from random import randint
import time
def decorate(func):
def wrapper(*args):
print('----正在校验中----')
n = randint(1,5)
time.sleep(n)
print('校验完毕,用时{}秒'.format(n))
func(*args)
return wrapper
@decorate
def f(name,age):
print('{} is {}.'.format(name,age))
f('Dio Brando',121)
如果装饰器是多层的,谁距离函数最近就优先使用哪个装饰器
def decorate1(func):
def wrapper():
func()
print('------>第一家刷漆')
return wrapper
def decorate2(func):
def wrapper():
func()
print('------>第二家铺地板')
print('------>第二家装门')
return wrapper
@decorate2
@decorate1
def house():
print('我是毛坯房')
house()
装饰器带参数
带参数的装饰器是三层的:
- 最外层的函数负责接收装饰器参数;
- 里面的内容还是原装饰器的内容
def outer(a):
def decorate(func):
def wrapper(*args,**kwargs):
func(*args)
print('------>铺地砖{}块'.format(a))
return wrapper
return decorate
@outer(a=10)
def house(time):
print('我是{}拿到的毛坯房'.format(time))
house('6-11')
8、匿名函数
简化函数定义
格式
lambda 参数1,参数2... : 运算
举例:
s = lambda a,b:a+b
需要运用匿名函数的:
- max()
- min()
- sorted()
- map()
- reduce()
- filter()
9、递归函数
特点:
- 自己调用自己
- 要有入口、出口
10、作用域:LEGB
- L:local 本地 局部变量
- E:enclosing 嵌套
- G:global 全局
- B:built-in 内置的