一 、为什么用函数:
1、 代码重复
2、 代码可描述性不高
3、 代码太low
函数是以功能为导向,一个函数封装一个功能,函数减少代码的重复性,增强了代码的可读性。
二 、函数的结构、调用和返回值
def func():
pass
func()
return:给函数的执行者返回具体的值、在函数中遇到return直接结束函数。
1.函数中没有return或者只有写一个return,函数的执行者得到的是None。
2.函数中return后面只写一个参数 执行者得到的就是这个参数(不改变值得类型)
3.return 返回多个元素 是以元组的形式返回给函数的执行者。
三 、函数的传参
分两个角度:实参、形参。
实参角度:
位置参数 (从左至右,按照顺序,一一对应)
关键字参数 (一一对应)
混合参数 (位置参数一定要在关键字参数的前面。)
形参角度:
位置参数 (与实参角度参数一样)
默认参数 (意义:普遍经常使用的。一定在位置参数后面,不传参数即沿用默认的参数)
动态参数 (*args,**kwargs)
#*代表聚合。 他将实参角度所有的位置参数聚合成一个元组,赋值给了 args
#** 将实参角度所有的关键字参数聚合到一个字典中,将这个字典赋值给了kwargs
#*的魔性用法:(当函数执行时:*代表打散)返回的是元祖
#** 的魔性用法:(当函数执行中:**dict 代表打散)返回的是字典
仅限关键字参数(没用)
四 、 名称空间、作用域
全局名称空间:py文件运行时,存放的是执行的py文件(除去函数内部)的所有的变量与值(地址)的对应关系,整个py文件结束之后,才会消失.
临时(局部)名称空间:函数执行时,在内存中临时开辟的一个空间,存在的函数中的变量与值得对应关系,随着函数的结束而消失.
内置名称空间:print input 内置函数等.
LEGB原则:(从局部找时)局部名称空间 ---> 全局名称空间 ---> 内置名称名称空间
全局作用域:内置名称空间 全局名称空间
局部作用域:局部名称空间(局部作用域不能改变全局变量)
globals(获取全局作用域)
locals(获取当前作用域)
global:可以在局部作用域声明一个全局变量,也可以更改全局变量
nonlocal:不能够操作全局变量。(内层函数对外层函数的局部变量进行修改。并且在当前作用域创建(复制)一份此变量。)
五 、迭代器和生成器
内部含有__iter__方法的对象,就是可迭代对象(dir()判断是否是可迭代对象)
内部含有__iter__并且含有__next__方法的对象,就是迭代器(迭代器可以迭代取值。利用next()进行取值)
可迭代对象:可迭代对象是一个操作比较灵活,直观,效率相对高,但是比较占用内存的数据集。
迭代器:迭代器是一个非常节省内存,满足惰性机制,但是效率相对低,操作不灵活的数据集。
生成器和迭代器的唯一的区别:生成器是我们自己用python代码构建的数据结构。迭代器都是提供的,或者转化得来的。
获取生成器的三种方式:
生成器函数
生成器表达式
python内部提供的一些
yield 、return区别
return:函数中只存在一个return结束函数,并且给函数的执行者返回值。(多个值通过元组的形式返回)
yield:只要函数中有yield那么它就是生成器函数而不是函数了。生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next。(多个值以元组的形势返回)
yield from 将一个可迭代对象的每一个元素返回给next
yield from 节省代码,提升效率(代替了for循环)
六 、列表表达式和生成器表达式
列表推导式:一行代码构建一个有规律比较复杂的列表
1.循环模式: [变量(加工后的变量) for 变量 in iterable]
2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]
生成器表达式:与列表推导式一样(取值用next)
七 、内置函数
Python有68种内置函数
eval() 慎用 eval 剥去字符串的外衣,返回里面的本质
exec() 代码流,过程
hash() 哈希值
help() 帮助
callable() 判断一个对象是否可被调用
int() 取整数
bin() 将十进制转换成二进制并返回
ord() 输入字符找该字符编码的位置
chr() 输入位置数字找出其对应的字符
repr() 原形毕露
sep 设定分割符
end 默认是换行可以打印到一行
list:创建列表
dict:创建字典
abs() 获取绝对值
sum() 数字相加求和
min 可以加功能 以绝对值的方式取最小值(可以加匿名函数)
max() 与min 相同。
reversed() 对一个可迭代对象进行翻转,返回一个迭代器
zip 拉链方法 返回一个迭代器
sorted 排序(可以加key)
filter 返回一个生成器 # 生成器表达式的筛选模式
map 返回一个迭代器,相当于生成器表达式:循环模式
reduce python3x 从内置函数剔除了。是一个累加函数这个函数必须接受两个参数,把结果继续和序列的下一个元素做累计算
八 、 闭包、装饰器
闭包有什么作用:封装东西、保证数据安全
被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,
自由变量不会再内存中消失。
如何判断一个嵌套函数是不是闭包
闭包只能存在嵌套函数中。
内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
开放封闭原则
装饰器:在不改变原函数的代码以及调用方式的前提下,为其增加新功能
标准的装饰器:
def wrapper(f):
def inner(*args,**kwargs):
'''添加额外的功能:执行被装饰函数之前的操作'''
ret = f(*args,**kwargs)
''''添加额外的功能:执行被装饰函数之后的操作'''
return ret
return inner
带参数的装饰器:
def wrapper_out(n):
def wrapper(f):
def inner(*args,**kwargs):
'''添加额外的功能:执行被装饰函数之前的操作'''
ret = f(*args,**kwargs)
''''添加额外的功能:执行被装饰函数之后的操作'''
return ret
return inner
@wrapper_out('参数')
多个装饰器装饰一个函数:
def wrapper1(func1):
def inner1():
print('wrapper1 ,before func')
func1()
print('wrapper1 ,after func')
return inner1
def wrapper2(func2):
def inner2():
print('wrapper2 ,before func')
func2()
print('wrapper2 ,after func')
return inner2
@wrapper2
@wrapper1
def f():
print('in f')
f()
九 、 递归函数
递归的最大深度1000层 : 为了节省内存空间,不要让用户无限使用内存空间
一个递归函数要想结束,必须在函数内写一个return,并且return的条件必须是一个可达到的条件
递归个列表里面的列表
l1 = [1, 3, 5, ['上海','北京', 34, [33, 55, [11,33]]], [77, 88],66]
def func(alist):
for i in alist:
if type(i) == list:
func(i)
else:
print(i) #python3
func(l1)