函数
函数的定义
1 deftest(x):2 "The function definition"
3 x += 1
4 return x
def:定义函数的关键字
test:函数名
():内可定义形参
“”:文档描述,非必要,但添加后可使得函数更易理解
x += 1:泛指代码块或程序处理逻辑,最好不要过多,让函数的功能简洁明了
return :定义返回值
调用运行:可以带参数也可以不带
函数名()
1 deftest(x):2 "The function definition"
3 x += 1
4 returnx5 y = test(5)6 print(y)7 #6
8 deftest1():9 "The function definition"
10 x = 5
11 y = x * 2 + 1
12 returny13 y =test1()14 print(y)15 #11
注意:函数名一旦重名,后写的函数会覆盖先写的函数,因为Python是从上到下读取的。
使用函数的意义
实现特定的功能,避免重复代码
1、代码重用
2、保持一致性,易于维护
3、可扩展性
函数与过程
过程本质是函数,但是没有设定返回值,而在Python中,会自动为过程返回None
1 deftest01():2 x = "I like Python"
3 print(x)4 returnx5 t1 =test01()6 print(t1)7 """
8 I like Python9 I like Python10 """
11 deftest02():12 x = "I like Python"
13 print(x)14 t2 =test02()15 """
16 I like Python17 None18 """
返回值数:0 => None
返回值数:1 => 返回object
返回值数:>1 =>返回tuple
函数参数
形参:只有在被调用时才分配内存单元,在调用结束后,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。
实参:可以是常量、变量、表达式、函数等,无论是何种类型,在进行函数调用时,它们都必须有明确的值,以便将这些值传给形参。因此,应预先用赋值、输入等方法使参数获得确定值。
位置参数和关键字:标准调用:实参和形参位置意义对应;关键字调用:位置无需固定
1 def test(x,y,z): #x,y,z是形参
2 h = x + y **z3 returnh4 t1 = test(1,2,3) #1,2,3是实参,属于位置参数
5 print(t1)6 t2 = test(x = 2, y =2, z = 2) #属于关键字调用
7 print(t2)8 """
9 910 611 """
注意:二者混用时,位置参数一定要在关键字参数的 左边
默认参数
1 def test(x,type="None"): #type是默认参数
2 print(x)3 print(type)4
5 test(5)6 test(5,type="Class")7 """
8 59 None10 511 Class12 """
参数组
**字典 *列表
1 def test(x,*args):
2 print(x)3 print(args)4 print(args[0])5 test(1,2,3,5)6 """
7 18 (2, 3, 5)9 210 """
1 def test(x,*args,**kwargs):2 print(x)3 print(args)4 print(kwargs)5 test(1,2,3,5,7,9,y=9)6 """
7 18 (2, 3, 5, 7, 9)9 {'y': 9}10 """
全局变量与局部变量
定头写的是全局变量,在整个py文件中都可以调用
局部变量是子程序中定义的变量,只能在子程序中调用
1 name = "Sister" #全局变量
2 deftest():3 name = "Jenny" #局部变量
4 print("change_name:",name)5 test()6 #change_name: Jenny
强制修改成全部变量的方法: 用global
1 name = "Sister"
2 deftest():3 global name #将其定义为全局变量
4 name = "Jenny"
5 print("change_name:",name)6 test()7 print(name)8 """
9 change_name: Jenny10 Jenny11 """
注意:
1、如果函数内无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值,但对于可变类型,可以对内部元素进行操作
1 name = "Sister"
2 deftest():3 name = "Jenny"
4 print("I love", name)5 test()6 print(name)7 """
8 I love Jenny9 Sister10 """
11 name1 = ["Allen", "Paul"]12 deftest1():13 name1.append("Jenny")14 print("I love", name1)15 test1()16 print(name1)17 """
18 I love ['Allen', 'Paul', 'Jenny']19 ['Allen', 'Paul', 'Jenny']20 """
2、如果函数中有global关键字,变量本质上就是全局的特定变量,可读取可赋值
3、全局变量名全用大写,局部变量名全用小写
函数的嵌套
1 def huangwei(): #执行顺序: 1→14→2、3→4→12→5、6→7→10→11→8、9→13
2 name = "黄伟"
3 print(name)4 defliuyang():5 name = "刘洋"
6 print(name)7 defnulige():8 name = '沪指花'
9 print(name)10 print(name)11 nulige()12 liuyang()13 print(name) #只调用这个子函数内部的变量
14 huangwei()15 """
16 黄伟17 刘洋18 刘洋19 沪指花20 黄伟21 """
注意:可以用nonlocal直接指定上一级变量
前向引用 :函数即变量
1 deftop():2 print("from top to bottom")3 defbottom():4 print("from bottom to top")5 top()6 bottom()7 """
8 from bottom to top9 from top to bottom10 """
11 defbottom():12 print("from bottom to top")13 top()14 deftop():15 print("from top to bottom")16 bottom()17 """
18 from bottom to top19 from top to bottom20 """
递归
defcalc(n):print(n)
calc(n)
calc(10)#Wrong
1 importtime2 defcalc(n):3 print(n)4 time.sleep(1)5 calc(n)6 calc(10)7 #结果会不停输出10
递归的特性:
1、必须有一个明确的结束条件
满足某个条件 return
1 defcalc(n):2 print(n)3 if int(n / 2) ==0:4 returnn5 res = calc(int(n / 2))6 returnres7 res = calc(10)8 print(res)9 """
10 1011 512 213 114 115 """
2、递归的效率不高,递归层次过多会导致栈溢出。
作用域
1 deftest01():2 print("test")3 deftest02():4 print("test2")5 return 1
6 res =test02()7 print(res)8 #test2
9 #1
10 deftest1():11 print("test1")12 deftest2():13 print("test2")14 returntest115 res =test2()16 print(res)17 #test2
18 # 这是test
19 deftest1():20 print("test1")21 deftest2():22 print("test2")23 returntest124 res =test2()25 print(res())26 #test2
27 #test1 这是test1()的执行过程
28 #None 这是因为没有return值所以添加的默认值
函数运行的结果与其定义有关,与其在哪里调用无关
1 defname1():2 name = "1"
3 defname2():4 name = "2"
5 defname3():6 print(name)7 returnname38 returnname29 z =name1()10 print(z)11 #.name2 at 0x000001E8FFAFA488>
12 name2 =name1()13 name3 =name2()14 name3()15 #2
16 name1()()()17 #2