一、Python3 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,比如print()。用户自己创建函数,这被叫做用户自定义函数。
1.定义一个函数
定义一个功能函数的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数(参数列表)。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
(1)语法
默认情况下,参数值和参数名称是按函数声明中定义的的顺序匹配起来的。
1 def 函数名(参数列表): 2 函数体
1 def haauleon(i=3,j=5): 2 return (i+j) 3 4 m = int(input("please input m = ")) 5 n = int(input("please input n = ")) 6 print(haauleon(m,n))
运行结果:
please input m = 12
please input n = 21
33
2.函数调用
定义一个函数:给了函数一个名称,指定了函数里包含的参数列表和代码块结构。
这个函数的基本结构完成以后,可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。
1 def haauleon(l,w,h): 2 return (l*w*h) 3 4 def Haauleon(i,j,k): 5 return (i+j+k) 6 7 8 i = int(input("please input m = ")) 9 j = int(input("please input m = ")) 10 k = int(input("please input m = ")) 11 12 print(haauleon(i,j,k)) 13 print(Haauleon(i,j,k))
运行结果:
please input m = 2
please input m = 2
please input m = 2
8
6
3.参数传递
在 python 中,类型是属于对象的,而变量是没有类型的,所有的变量可以理解为“内存中一个对象的引用”,因此需要把变量和内存对象区分开。python 中一切皆对象,严格意义上不能说值传递还是引用传递,而是应该说传不可变对象和传可变对象。
1 a=[1,2,3] 2 3 a="Runoob"
以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型的,它仅仅只是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
(1)可更改(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 ,这里实际上是有一个新int类型的对象5被指定给了la所指向对象的第三个值,但是对于la来说,所指向的对象并没有发生变化,仍旧是那个有4个int对象的list。
python 函数的参数传递:
-
不可变类型:类似 c++ 的值传递,如 整形、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
-
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。
(2)Python传不可变类型的对象
1 def func(m): 2 return (m**2) 3 4 #引用n指向int类型的对象10 5 n = 10 6 7 #当传递给func()时,按照变量传值的方式,复制一个对象10传给func(),使得m也指向该对象10,当m=10^2时,则新生成一个int对象100,并让m指向它 8 print(func(n)) 9 10 #由于int类型的对象不可被更改,于是做了一个新的int对象100并令m指向它,但由于被变量n所指向的对象10没有发生变化,因此在外面的感觉就是函数并没有改变n的值 11 print(n)
运行结果:
100
10
(3)Python传可变类型的对象
可变对象在函数里修改了参数,那么在被调用函数的代码块里,原始的参数也被改变了。
1 def change(dicts): 2 #修改传入的字典 3 dicts["食佐饭未?"] = "未啊!" 4 print ("change()函数内: ", dicts) 5 return 6 7 haauleon = {"食佐饭未?":"食佐喇","食佐咩啊?":"人头饭咯"} 8 9 #调用change函数,传入函数的对象和修改内容的对象用的是同一个引用,即直接传引用,类似C++里面的传引用 10 change(haauleon) 11 12 print ("change()函数外: ", haauleon)
运行结果:
change()函数内: {'食佐饭未?': '未啊!', '食佐咩啊?': '人头饭咯'}
change()函数外: {'食佐饭未?': '未啊!', '食佐咩啊?': '人头饭咯'}
4.参数
以下是调用函数时可使用的正式参数类型:
- 必需参数
- 关键字参数
- 默认参数
- 不定长参数
(1)必需参数
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样,不然会出现语法错误。
1 def change(i,j,k): 2 if(k**2 == i**2 + j**2): 3 return ("直角三角形") 4 else: 5 return ("非直角三角形") 6 7 #调用change函数 8 print(change(3,4))
运行结果:
Traceback (most recent call last):
File "C:/Users/bringbuys/AppData/Local/Programs/Python/Python36-32/practice/mul.py", line 9, in <module>
print(change(3,4))
TypeError: change() missing 1 required positional argument: 'k'
1 def change(i,j,k): 2 if(k**2 == i**2 + j**2): 3 return ("直角三角形") 4 else: 5 return ("非直角三角形") 6 7 #调用change函数 8 print(change(3,4,5)) 9 print(change(3,4,6))
运行结果:
直角三角形
非直角三角形
(2)关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为Python 解释器能够用参数名匹配参数值。
1 def haauleon(hight,weight): 2 hight /= 100 3 weight /= 2 4 print("身高:",hight) 5 print("体重:",weight) 6 return 7 8 haauleon(weight = 140,hight = 186)
运行结果:
身高: 1.86
体重: 70.0
(3)默认参数
调用函数时,如果没有传递参数,则会使用默认参数。
1 def haauleon(hight = 199,weight = 145): 2 hight /= 100 3 weight /= 2 4 print("身高:",hight,end = "\t") 5 print("体重:",weight) 6 print("\n") 7 return 8 9 10 haauleon(hight = 186,weight = 140) 11 12 haauleon(weight = 140,hight = 186) 13 14 haauleon(hight = 186) 15 16 haauleon(weight = 140) 17 18 #从左至右第一个参数不能为空,否则会抛出异常 19 haauleon(hight,weight = 140)
运行结果:
身高: 1.86 体重: 70.0
身高: 1.86 体重: 70.0
身高: 1.86 体重: 72.5
身高: 1.99 体重: 70.0
Traceback (most recent call last):
File "C:/Users/bringbuys/AppData/Local/Programs/Python/Python36-32/practice/mul.py", line 20, in <module>
haauleon(hight,weight = 140)
NameError: name 'hight' is not defined
(4)不定长参数
需要一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。加了星号(*)的变量名会存放所有未命名的变量参数。基本语法如下:
1 def functionname([formal_args,] *var_args_tuple ): 2 "函数_文档字符串" 3 function_suite 4 return [expression]
1 def Haauleon(*virgos): 2 print(virgos) 3 Haauleon("帅气","英俊","潇洒",2345) 4 print("\n") 5 6 def Haauleon1(**vir): 7 print(vir) 8 Haauleon1(身高 = 186,体重 = 110,abc = "123") 9 print("\n") 10 11 def Haauleon2(*mm,**nn): 12 print(mm) 13 print(nn) 14 Haauleon2("帅气","英俊") 15 print("\n") 16 Haauleon2(身高 = 186,体重 = "110") 17 print("\n") 18 Haauleon2("帅气","英俊",身高 = 186) 19 print("\n") 20 21 def Haauleon3(var,*var_tuples,**var_dicts): 22 print(var) 23 print(var_tuples) 24 print(var_dicts) 25 Haauleon3(1,2,"帅气","hauleon",身高 = 186,体重 = 110,abc = "123") 26 27 #当同时存在tuples和dicts时,必须要使tuples参数列在dicts参数列前,这是由关键字参数位置决定的,否则会抛出异常SyntaxError: positional argument follows keyword argument 28 #Haauleon2(身高 = 186,体重 = 110,ABC,"帅气","英俊")
运行结果:
('帅气', '英俊', '潇洒', 2345)
{'身高': 186, '体重': 110, 'abc': '123'}
('帅气', '英俊')
{}
()
{'身高': 186, '体重': '110'}
('帅气', '英俊')
{'身高': 186}
1
(2, '帅气', 'hauleon')
{'身高': 186, '体重': 110, 'abc': '123'}
5.匿名函数
python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
(1).语法
1 #lambda 函数的语法只包含一个语句 2 lambda [arg1 [,arg2,.....argn]]:expression
1 #lambda只包含一个语句且只能是一个表达式 2 Compare = lambda i,j:j**i 3 print(Compare(2,8)) 4 5 #若lambda包含代码块则会抛出异常SyntaxError: invalid syntax 6 ''' 7 Compare = lambda i,j: 8 if(i>j): 9 print("i>j") 10 else: 11 print("i<=j") 12 '''
运行结果:
64
6.return语句
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
1 #sum()函数有返回值 2 def sum(arg1,arg2): 3 # 返回2个参数的和." 4 total = arg1 + arg2 5 print ("函数内total:: ", total) 6 return total; 7 8 #compare()函数没有返回值 9 def compare(i,j): 10 if(i>j): 11 mm = i - j 12 print("函数内mm:",mm) 13 else: 14 mm = i + j 15 print("函数内mm:",mm) 16 17 #调用sum()函数 18 total = sum(10,20); 19 print ("函数外total:: ",total) 20 print("\n") 21 22 #调用compare()函数 23 mm = compare(4,9) 24 print ("函数外mm:",mm)
运行结果:
函数内total:: 30
函数外total:: 30
函数内mm: 13
函数外mm: None
7.变量作用域
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
- L (Local) 局部作用域
- E (Enclosing) 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内建作用域
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。