---恢复内容开始---
Python 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
1 定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
2 return关键字的作用
return 是一个关键字,在pycharm里,你会看到它变成蓝色了。你必须一字不差的把这个单词给背下来。
这个词翻译过来就是“返回”,所以我们管写在return后面的值叫“返回值”
要研究返回值,我们还要知道返回值有几种情况:分别是没有返回值、返回一个值、返回多个值
没有返回值
不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况. 刚刚我们已经写过一个返回一个值的情况,只需在return后面写上要返回的内容即可。也可以返回任意多个、任意数据类型的值,返回的多个值会被组织成元组被返回,也可以用多个值来接收
只写return,后面不写其他内容,也会返回None,有的同学会奇怪,既然没有要返回的值,完全可以不写return,为什么还要写个return呢?这里我们要说一下return的其他用法,就是一旦遇到return,结束整个函数。
def ret_demo(): print(111) return print(222) ret = ret_demo() print(ret) 只写return
结果:
多个值接收
def ret_demo2(): return 1,['a','b'],3,4 #返回多个值,用一个变量接收 ret2 = ret_demo2() print(ret2) #返回多个值,用多个变量接收 a,b,c,d = ret_demo2() print(a,b,c,d) #用多个值接收返回值:返回几个值,就用几个变量接收 a,b,c,d = ret_demo2() print(a,b,c,d) 多个返回值的接收 多个值接收
结果:
3 参数
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
-
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
-
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
-
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
-
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
参数
以下是调用函数时可使用的正式参数类型:
- 位置参数
- 关键字参数
- 默认参数
- 混合参数
位置参数
位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用printme()函数,你必须传入一个参数,不然会出现语法错误:
s = 'fdsafsda' l2 = [1, 2, 3, 4, 5, 6, 5, 4, 3, 3, 'alex'] def my_len(x,y,z): #形参:形式参数 count = 0 for i in x: count += 1 return count ret = my_len(l2,s,'alex') # 按位置传参 print(ret) len(s)
结果:
2 关键字参数 关键字位置可以互换
def mymax(x,y): #此时x = 20,y = 10 关键字 x y # print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) #x关键字 y关键字 各自对应一个参数位置可以互换 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) 混合传参
结果:
4 默认参数
为什么要有默认参数:将变化比较小的值设置成默认参数
def func(name,sex='男'): with open('name_list','a',encoding='utf-8') as f1: f1.write('{} {} '.format(name,sex)) while True: name = input('请输入名字:') if '姐' in name: sex = input('请输入性别:') func(name,sex) # 混合 else: func(name)
结果:
5 动态参数 形参: 第3种 动态参数 *args 动态参数,不定长参数*args元组,他包含了你所有的位置参数.**kwargs包含所有关键字参数.
要在位置参数后面,否则*args会把所有所有收走
def func(a,b,c,*args): print(a) print(b) print(c) print(args,type(args)) func(1,2,'alex',3,4,)
结果:
**kwargs包含所有关键字参数. 放在位置参数,*args,默认参数后.
def func(a,b,c,*args,sex = '男',**kwargs): print(a) print(b) print(c) print(sex) print(args,type(args)) print(kwargs) func(1,2,'alex','wusir','ritian ',sex = '女',name = 'taibai',age = 21)
结果:
6 万能参数 后面有多少个数据都能接收
def func2(*args,**kwargs): #万能参数 print(args) print(kwargs) func2(1,2,3,5,name='alex',age=56)
结果;
7 魔法运算 将列表或字典内元素一个一个拿出来
# 魔法运算: def func(*args): print(args) li = [1,2,3] l2 = [4,5,6] func(li) #输出结果:([1, 2, 3],) func(*li) #输出结果:(1, 2, 3) func(*li,l2) #输出结果:(1, 2, 3, [4, 5, 6]) func(*li,*l2) #输出结果:(1, 2, 3, 4, 5, 6)
#*魔法运算:打散 def func2(*args,**kwargs): print(args) #(1,2,3) l1 = [1,2,3,] l2 = [1,2,3,2,3,100,2] func2(*l2,*l1)
def func3(*args,**kwargs): print(args) print(kwargs) dic = {'name':'alex','age':12} dic2 = {'name':'jin','age':22} func3(**{'name1':'alex','age1':12},**{'name2':'jin','age2':22},name3 = 'wusir')
结果;
名称空间:
全局名称空间,
局部名称空间,
input,print sum le
内置名称空间
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值顺序:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
在找寻变量时,从小范围,一层一层到大范围去找寻。
作用域
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
name = 'wusir' def func(): name = 'alex' # 取值范围 局部有先从局部找 print(name) func() def len(x): return x #取值范围 局部有 运行局部的 print(len([1,2,3]))
结果:
作用域的角度:
全局作用域 包括 全局名称空间,内置名称空间
局部作用域 包括 局部名称空间,
name = 'wusir' def func(): name = 'alex' print(name) print(globals()) #全局 print(locals()) #局部 func()
结果:
8 函数嵌套 一个函数执行完以后才会执行后面的代码
print(111) def fun2(): print(222) def fun3(): print(666) print(444) fun3() print(888) print(333) fun2() print(555)
结果;
9 global声明一个全局变量,如果在函数内改变,全局下也改变.(不可变类型时使用,可变类型不需要)
#global 1,声明一个全局变量 #引用全局变量,并改变 def func(): global a a = 2 print(a) func() print(a)
结果:
如果可变类型就不需要global 因为本身就能改变
#可变的数据类型 l1 = [1,2,3] def func(): l1.append(444) func() print(l1)
结果:
nonlocal与global相似,但是它只是作用于嵌套作用域,而且只是作用在函数里面
1,不能修改全局变量。
2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。被引用的外层不会被改变.
def func(): name = 'wusir' def inner(): nonlocal name name = 'taibai' print(name) print(name) inner() print(name) func()
结果:
父级函数下被引用,对本身和下一级函数有用,
def add_b(): b = 42 def do_global(): b = 10 print(b) def dd_nonlocal(): nonlocal b b = b + 20 print(b) dd_nonlocal() print(b) do_global() print(b) add_b()
结果:
---恢复内容结束---
Python 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
1 定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
2 return关键字的作用
return 是一个关键字,在pycharm里,你会看到它变成蓝色了。你必须一字不差的把这个单词给背下来。
这个词翻译过来就是“返回”,所以我们管写在return后面的值叫“返回值”
要研究返回值,我们还要知道返回值有几种情况:分别是没有返回值、返回一个值、返回多个值
没有返回值
不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况. 刚刚我们已经写过一个返回一个值的情况,只需在return后面写上要返回的内容即可。也可以返回任意多个、任意数据类型的值,返回的多个值会被组织成元组被返回,也可以用多个值来接收
只写return,后面不写其他内容,也会返回None,有的同学会奇怪,既然没有要返回的值,完全可以不写return,为什么还要写个return呢?这里我们要说一下return的其他用法,就是一旦遇到return,结束整个函数。
def ret_demo(): print(111) return print(222) ret = ret_demo() print(ret) 只写return
结果:
多个值接收
def ret_demo2(): return 1,['a','b'],3,4 #返回多个值,用一个变量接收 ret2 = ret_demo2() print(ret2) #返回多个值,用多个变量接收 a,b,c,d = ret_demo2() print(a,b,c,d) #用多个值接收返回值:返回几个值,就用几个变量接收 a,b,c,d = ret_demo2() print(a,b,c,d) 多个返回值的接收 多个值接收
结果:
3 参数
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
-
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
-
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
-
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
-
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
参数
以下是调用函数时可使用的正式参数类型:
- 位置参数
- 关键字参数
- 默认参数
- 混合参数
位置参数
位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用printme()函数,你必须传入一个参数,不然会出现语法错误:
s = 'fdsafsda' l2 = [1, 2, 3, 4, 5, 6, 5, 4, 3, 3, 'alex'] def my_len(x,y,z): #形参:形式参数 count = 0 for i in x: count += 1 return count ret = my_len(l2,s,'alex') # 按位置传参 print(ret) len(s)
结果:
2 关键字参数 关键字位置可以互换
def mymax(x,y): #此时x = 20,y = 10 关键字 x y # print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) #x关键字 y关键字 各自对应一个参数位置可以互换 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) 混合传参
结果:
4 默认参数
为什么要有默认参数:将变化比较小的值设置成默认参数
def func(name,sex='男'): with open('name_list','a',encoding='utf-8') as f1: f1.write('{} {} '.format(name,sex)) while True: name = input('请输入名字:') if '姐' in name: sex = input('请输入性别:') func(name,sex) # 混合 else: func(name)
结果:
5 动态参数 形参: 第3种 动态参数 *args 动态参数,不定长参数*args元组,他包含了你所有的位置参数.**kwargs包含所有关键字参数.
要在位置参数后面,否则*args会把所有所有收走
def func(a,b,c,*args): print(a) print(b) print(c) print(args,type(args)) func(1,2,'alex',3,4,)
结果:
**kwargs包含所有关键字参数. 放在位置参数,*args,默认参数后.
def func(a,b,c,*args,sex = '男',**kwargs): print(a) print(b) print(c) print(sex) print(args,type(args)) print(kwargs) func(1,2,'alex','wusir','ritian ',sex = '女',name = 'taibai',age = 21)
结果:
6 万能参数 后面有多少个数据都能接收
def func2(*args,**kwargs): #万能参数 print(args) print(kwargs) func2(1,2,3,5,name='alex',age=56)
结果;
7 魔法运算 将列表或字典内元素一个一个拿出来
#*魔法运算:打散 def func2(*args,**kwargs): print(args) #(1,2,3) l1 = [1,2,3,] l2 = [1,2,3,2,3,100,2] func2(*l2,*l1) def func3(*args,**kwargs): print(args) print(kwargs) dic = {'name':'alex','age':12} dic2 = {'name':'jin','age':22} func3(**{'name1':'alex','age1':12},**{'name2':'jin','age2':22},name3 = 'wusir')
结果;
名称空间:
全局名称空间,
局部名称空间,
input,print sum le
内置名称空间
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值顺序:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
在找寻变量时,从小范围,一层一层到大范围去找寻。
作用域
作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
name = 'wusir' def func(): name = 'alex' # 取值范围 局部有先从局部找 print(name) func() def len(x): return x #取值范围 局部有 运行局部的 print(len([1,2,3]))
结果:
作用域的角度:
全局作用域 包括 全局名称空间,内置名称空间
局部作用域 包括 局部名称空间,
name = 'wusir' def func(): name = 'alex' print(name) print(globals()) #全局 print(locals()) #局部 func()
结果:
8 函数嵌套 一个函数执行完以后才会执行后面的代码
print(111) def fun2(): print(222) def fun3(): print(666) print(444) fun3() print(888) print(333) fun2() print(555)
结果;
9 global声明一个全局变量,如果在函数内改变,全局下也改变.(不可变类型时使用,可变类型不需要)
#global 1,声明一个全局变量 #引用全局变量,并改变 def func(): global a a = 2 print(a) func() print(a)
结果:
如果可变类型就不需要global 因为本身就能改变
#可变的数据类型 l1 = [1,2,3] def func(): l1.append(444) func() print(l1)
结果:
nonlocal与global相似,但是它只是作用于嵌套作用域,而且只是作用在函数里面
1,不能修改全局变量。
2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。被引用的外层不会被改变.
def func(): name = 'wusir' def inner(): nonlocal name name = 'taibai' print(name) print(name) inner() print(name) func()
结果:
父级函数下被引用,对本身和下一级函数有用,
def add_b(): b = 42 def do_global(): b = 10 print(b) def dd_nonlocal(): nonlocal b b = b + 20 print(b) dd_nonlocal() print(b) do_global() print(b) add_b()
结果: