分分钟钟学会Python - 函数(function)
函数(function)
1 基本结构
本质:将多行代码拿到别处并起个名字,以后通过名字就可以找到这行代码并执行
-
应用场景:
- 代码重复执行
- 代码量很多超过一屏,可以选择通过函数进行代码的分割
- 写代码方式:面向过程----函数式编程(多)----面向对象编程
-
基本结构
# 函数的定义 def 函数名(): 函数内容 pass # 函数的执行 函数名()
# 示例一 def list_data(): v = [11,54,52] print(v[1]) list_data() # 54
- 函数如果不被调用,则内部永远不会被执行
# 练习题 # 1.请写一个函数,函数计算列表 info = [11,22,33,44,55]中所有元素的和 def list_data(): s = 0 info = [11, 22, 33, 44, 55] for i in info: s = s + i print(s) list_data() # 165 # 2.请写一个函数,用函数将列表拼接起来 def new_list(a,b): c = [] c.extend(a) c.extend(b) print(c) a1 = [555,4,6,5,6] a2 = [5646,86,6,] new_list(a1,a2) # [555, 4, 6, 5, 6, 5646, 86, 6] # 3.计算一个列表的长度 def list_len(age): conten = 0 for i in age: conten +=1 print(conten) v = [11,2,'rtffd','r','g','fsd',77] list_len(v) # 7
-
返回值
- 函数没有返回值,默认返回:none
- 函数内部执行过程中遇到return,就终止。
- return 可以返回任意类型
- 如果return后面写了多个结果,,返回给调用者一个tuple(元祖),调用者可以直接使用解构获取多个变量
```python
def func():
return (1,2,3)v = func()
print(v) # (1, 2, 3)特殊:多个返回值,返回值为元组
def func(age): #函数 return 9 # 返回默认值为9,默认:return none val = func('asdfghj')
```python
示例一
1.让用户输入一段字符串,计算字符串中有多少个a字符的个数,有多少就在a.txt中写多少个"大王八"
def jisuan_a(aa):
s = 0
for i in aa:
if i =='a':
s+=1
return s
def xieru_d(bb):
if len(bb) == 0:
return false
with open('a.txt',mode='w',encoding='utf-8') as f:
f.write(bb)
return true
a = input("请用户输入")
a1 = jisuan_a(a)
b = "大王八" * a1
b1 = xieru_d(b)
print(b1) -
总结
# 情况一 def f1(): pass f1() # 情况二 def f2(a1): pass f2(123) # 情况三 def f3(): return 1 v1 = f3() # 情况四 def f4(a1,a2): #.... return 333 v2 = f4(1,22)
2 参数
-
形参、实参
def get_data(a):#a为形式参数(或形参) v = [1,5,6,,8,5] print(v[a]) get_data(1)# 1在调用函数是传递叫:实际参数(实参) # 严格按照顺序传参数:位置方式传参。 # 实际参数可以是任意类型。
-
基本参数
- 任意个数
- 任意类型
def func(a1,a2,a3): print(a1,a2,a3) func(1,"asdf",true) # 1 asdf true
-
位置传参(调用函数并传入函数)【执行】
def func(a1,a2): print(a1,a2) func(11,22) # 11 22
-
关键字传参 【执行】
def func(a1,a2): print(a1,a2) func(a2=11,a1=22) # 22 11
- 位置传参>关键字传参(顺序)
- 位置传参 + 关键字传参 = 总传参个数
- 前面是关键字传参,后面也必须关键字传参
-
默认参数 【参数】 对于函数的默认值慎用可变类型
# 如果要想给value设置默认是空列表 # 不推荐(坑) def func(data,value=[]): pass # 推荐 def func(data,value=none): if not value: value = []
- def func(a,b=[]) 有什么陷阱?
# 典例一 def func(a,b=[]): b.append(a) return b l1 = func(1) print(l1) # [1] l2 = func(2,[11,22]) print(l2) # [11,22,2] l3 = func(3) print(l3) # [1,2]
-
万能参数【打散】
-
*args
-
可以接受任意个数的位置参数,并将参数转换成元组.
-
调用函数无 *
def func(*args): print(args) func((1,2,3,4)) # ((1,2,3,4),) func([1,2,3,4]) # ([1, 2, 3, 4],)
-
调用函数有 *
def func(*args): print(args) func(*(1,2,3,4)) # (1, 2, 3, 4) func(*[1,2,3,4]) # (1, 2, 3, 4)
-
-
只能用位置传参
def func(*args): print(args) func(1) # () func(1,2) # (1,2) func((11,22,33,44,55)) # ((11,22,33,44,55),) func(*(11,22,33,44,55)) # (11,22,33,44,55)
-
-
**kwargs
-
可以接受任意个数的关键字参数,并将参数转换成字典。
-
调用函数无 **
def func(**kwargs): print(kwargs) func(k1=1,k2="alex") # {'k1':1,'k2':'alex'}
-
调用函数有**
def func(**kwargs): print(kwargs) func(**{'k1':'v2','k2':'v2'}) # {'k1':'v2','k2':'v2'}
-
只能用关键字传参
-
综合应用:无敌 + 无敌 => 真无敌
def func(*args,**kwargs): print(args,kwargs)
-
-
-
参数相关重点:
-
定义函数
def func1(a1,a2): pass def func2(a1,a2=none): pass def func3(*args,**kwargs): pass
-
调用函数
位置参数 > 关键字参数
-
3 作用域
-
python中
py文件:全局作用域
-
函数:局部作用域
a = 1 def s1(): x1 = 666 print(x1) #666 print(a) #1 print(b) #2 b = 2 print(a) #1 s1() a = 88888 def s2(): print(a,b) #88888,2 s1() #666,88888,2 s2()
-
一个函数是一个作用域
def func(): x = 9 print(x) #9 func() print(x) #9
-
作用域中查找数据规则:优先在自己的作用域找数据,自己没有就去 "父级" -> "父级" -> 直到全局,全部么有就报错。注意:父级作用域中的值到底是什么?
# 示例一 x = 10 def func(): x = 9 print(x) #9 func()
-
子作用域中只能 找到父级中的值 ,默认无法重新为父级的变量进行赋值,但可以修改。(global/nonlocal可以强制做)
- global :对全局的变量进行赋值
- nonloca : 找到上一级的局部变量进行赋值
# 示例一 name = 'abc' def func(): name = 'def' # 在自己作用域再创建一个这样的值。 print(name)# def func() print(name)# abc
-
总结
-
参数
- 调用(执行)函数时,传参:位置参数 > 关键字参数
- 定义函数:
- def func(a)
- def func(a,b=none) # 对于默认值,如果是可变类型,----> 坑。
- def func(*args,**kwargs)
-
作用域
- 函数为作用域
- 自己 > 父级 > 父级 > 全局 【读/修改(可变)】
- 重新赋值:
- global
- nonlocal
-
全部变量以后必须全部是大写
user_list = [11,22,3] def func(): name = 'asdf' user_list.append(12) user_list.append(name) func() print(user_list)
-
4 函数小高级
-
函数名作为变量
- 带括号就执行函数,返回函数返回值;不加括号指向函数地址,函数不执行
- 函数可以作为字典的键值,可以作为键
# 典例一 def func(): print(123) v1 = func # func函数不执行 func # func函数不执行 v1() # 执行func函数
-
函数可以当作参数进行传递
- 当参数时有(),得到返回值;当参数时无(),得到函数地址
def func(arg): print(arg) func(1) # 执行func 1 func([1,2,3,4]) # 执行func [1,2,3,4] def show(): return 999 func(show) # show不执行 指向函数地址 func(show()) # show执行 999
-
数据类型中的方法到底有没有返回值?
-
无返回值
v = [11,22,33] v.append(99) # 无返回值
-
仅有返回值:
v = "alex" result = v.split('l') v = {'k1':'v2'} result1 = v.get('k1') result2 = v.keys()
-
有返回+修改数据
v = [11,22,33] result = v.pop()
-
常用需要记住
- str 字符串的所有方法基本上都是返回值为新值
- strip,返回字符串
- split,返回列表
- replace,返回字符串
- join,返回字符串。
- list 列表所有方法基本上都是返回值none
- append,无
- insert,无
- pop,返回要删除的数据
- remove,无
- find/index,返回索引的位置。
- dict
- get ,返回指定键值
- keys,返回所有键
- values,返回所有值
- items,返回所有键值对
- str 字符串的所有方法基本上都是返回值为新值
-
-
函数内部的数据是否会混乱。
- 函数内部执行相互之间不会混乱
- 执行完毕 + 内部元素不被其他人使用 => 销毁
5 函数中高级
-
函数做返回值
- 就找函数何时被谁创建
def func(): print(123) #输出123 def bar(): return fun #返回函数fun v = bar() #执行函数bar() v() # 执行函数func()
-
闭包
- 闭包概念:为函数创建一块区域并为其维护自己数据,以后执行时方便调用。
- 闭包应用场景:装饰器、sqlalchemy源码
- a函数里面有b函数,并且返回值为b函数(b函数只被调用,没被执行;b函数引用a函数的变量)
def func(name): def inner(): print(name) return inner v1 = func('alex') # 执行func()函数值为alex,返回inner v1() #执行inner()函数,输出alex v2 = func('eric') v2()
-
高阶函数
- 把函数当做参数传递
- 把函数当做返回值
- 对函数进行复制
-
递归
-
含义:函数自己调自己(效率低)
def func(): print(1) func() func() # 示例 def func(i): print(i) func(i+1) func(1) # 1,2,3---988报错,死循环
-
斐契那波数列(有限制)
def func(a,b): # 1 # 1 # 2 # 3 # 5 print(b) func(b,a+b) func(0,1)
-
递归函数返回值
# 示例一 def func(a): if a == 5: return 100000 result = func(a+1) + 10 return result
-
5.5 lambda 表达式
-
用于表示简单的函数。
# 三元运算,为了解决简单的if else的情况,如: if 1 == 1: a = 123 else: a = 456 # 相当于 a = 123 if 1==1 else 456 print(a)
# lambda表达式,为了解决简单函数的情况,如: def funa(a1,a2): return a1 + 100 print(funa(1,3)) # 101 # 相当于 func = lambda a1,a2: a1+100 print(func(1,3)) # 101
7 内置函数
-
强制转换
- dict() list() tuple() int() str() bool() set()
-
输入和输出
- input print
-
其他函数
- len(长度) open(打开) id(查看内存) range(输出列表) type(查看类型)
-
数学相关
- abs(绝对值) float(转成浮点型:小数) max(找到最大值) min(找到最小值) sum(求和) divmod(求两数相除商和余数,多用于分页)
5.进制转换
bin,将十进制转化成二进制(0b)
oct,将十进制转换成八进制(0o)
int,将其他进制转化成十进制
hex,将十进制转换成十六进制(0x)
-
编码相关
chr,将十进制数字转换成unicode编码中的对应字符。
ord,将字符转换成unicode编码中的对应数字
-
高级函数
-
map,会根据提供的函数对指定序列做映射
- 第一个参数必须是一个函数
- 第二个函数必须是可迭代类型(可以for循环)
- py2最后返回一个列表;py3最后返回一个对象(节省内存)
循环每个元素(第二个参数),然后让每个元素执行函数(第一个)参数,将每个函数 执行的结果保存到新的列表中,并返回。
-
filter,函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
循环每个元素(第二个参数),然后让每个元素执行函数(第一个)参数进行判断,然后返回 true 或 false,最后将返回 true 的元素放到新列表中。
-
reduce,函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
-
type,查看类型/判断对象是否是类的实例(找到头)
issubclass 判断类是否是子类(到头都是)
isinstance 判断obj是否是foo类或其基类的实例(对象),找到头都是
super 根据self对象所属类的继承关系,按照顺序挨个找func方法并执行(找到第一个就不在找了)
8 推导式
-
列表推导式
-
基本格式
v1 = [i for i in 可迭代对象 ] v2 = [i for i in 可迭代对象 if 条件 ] # 条件为true才进行append
-
-
集合推导式
v1 = { i for i in 'alex' }
-
字典推导式
v1 = { 'k'+str(i):i for i in range(10) }