函数
python内置函数
绝对值:abs()
平方根:sqrt()
平方:power()
将整数转换为‘0x’前缀的十六进制字符串:hex()
将整数转换为‘0o’前缀的八进制字符串:oct()
数据类型转换函数:int()、float()、str()、bool()
导包:import 包名
练习题
请利用Python内置的hex()函数把一个整数转换成十六进制表示的字符串:
1 2 3 4 5 n1 = 255 n2 = 1000 print (str (hex (n1)))print (str (hex (n2)))
定义函数
用def语句定义函数
如自定义一个abs函数并检验函数功能,其代码如下:
1 2 3 4 5 6 7 def my_abs (x ): if x>=0 : return x else : return -x x=int (input ()) print (my_abs(x))
在python交互环境中定义函数时,python会出现...的提示,函数定义结束后需要按两次回车使其重新回到>>>提示符下,如下图所示:
空函数
定义一个空函数,用pass语句来作为占位符。
参数检查
如果要函数参数传入类型不对时需要抛出参数错误的信息,可用内置函数isinstance()检查参数,如if not isinstance(x,(int,float))语句,若传入了整数与浮点数之外的参数类型,函数就会抛出一个错误来提醒传参不对。
函数返回
函数体内部用return返回函数结果
函数执行完毕也没有return语句时,自动return None。
函数的return可以返回多个值 ,值之间用半角逗号 隔开,如return a,b
注意python返回值实际上是返回一个tuple,并非是返回两个值,比如以下代码:
1 2 3 4 5 6 7 8 9 10 def move (x,y ): return x+50 ,y+20 x=int (input ()) y=int (input ()) t=move(x,y) print (t)、50 100 (100 , 120 )
练习题
请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程
a x 2 + b x + c = 0
的两个解。
提示:
计算平方根可以调用math.sqrt()函数:
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import mathdef quadratic (a,b,c ): t=math.sqrt(float (b*b-4 *a*c)) p=(-b+t)/(2 *a) q=(-b-t)/(2 *a) return p,q print ('quadratic(2, 3, 1) =' , quadratic(2 , 3 , 1 ))print ('quadratic(1, 3, -4) =' , quadratic(1 , 3 , -4 ))if quadratic(2 , 3 , 1 ) != (-0.5 , -1.0 ): print ('测试失败' ) elif quadratic(1 , 3 , -4 ) != (1.0 , -4.0 ): print ('测试失败' ) else : print ('测试成功' ) quadratic(2 , 3 , 1 ) = (-0.5 , -1.0 ) quadratic(1 , 3 , -4 ) = (1.0 , -4.0 ) 测试成功
默认参数
自定义函数可以设置默认参数。如次方函数可以设为默认平方,需要计算其他次方的时候再传次方的参数。代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def my_power (x,n=2 ): t=1 while (n>0 ): n=n-1 t=x*t return t x=int (input ()) n=int (input ()) print (my_power(x))print (my_power(x,n))3 4 9 81
注意:
设置默认参数时。必选参数在前,默认参数在后
当函数有多个参数时,变化大的参数放前面,变化小的参数可以作为默认参数
默认参数必须指向不变对象
可变参数
传入的参数个数是可变的称为可变参数,形式为*参数名。
可变参数允许传入0个或任意个参数 ,这些参数在函数调用时自动组装为一个tuple 。
在参数个数不确定时,定义可变参数和定义一个list和tuple参数相比,区别在于仅在参数前加了个*号,而在函数内部,参数接收到的是一个tuple,函数代码是完全不用变的。此时调用函数时可传入任意个参数calc(1,2)也可以传入0个参数clac()。
将list或tuple元素变成可变参数传进函数中,可写成:
1 2 nums=[1 ,2 ,3 ] calc(*nums)
关键字参数
关键字参数允许传入0个或任意个含参数名 的参数,这些参数在函数内部自动组装为一个dict ,形式为**参数名。
关键字参数可以拓展函数的功能,如下所示:
1 2 3 4 5 6 7 8 9 def person (name,age,**kw ): print ('name:' ,name,'age:' ,age,'other:' ,kw) person('Lisi' ,34 ) person('Zhangsan' ,44 ,city='Shanghai' ) person('Wangwu' ,23 ,gender='M' ,job='teacher' ) name: Lisi age: 34 other: {} name: Zhangsan age: 44 other: {'city' : 'Shanghai' } name: Wangwu age: 23 other: {'gender' : 'M' , 'job' : 'teacher' }
将dict元素变成可变参数传进函数中,可写成:
1 2 3 4 5 6 def person (name,age,**kw ): print ('name:' ,name,'age:' ,age,'other:' ,kw) extra={'city' :'Shanghai' ,'job' :'teacher' } person('Wangwu' ,23 ,**extra) name: Wangwu age: 23 other: {'city' : 'Shanghai' , 'job' : 'teacher' }
命名关键字参数
若要限制关键字参数名字,只接收特定的参数可以用命名关键字参数,形式为*,限制参数名。命名关键字参数可以设置默认值,调用函数时必须传入参数名 。
函数定义如下,则表示只接收city和job作为关键字参数:
1 2 def person (name,age,*,city,job ): print (name,age,city,job)
若函数定义中已经有一个可变参数,后面跟着的命名关键字参数就不需要特殊分隔符*了
1 2 def person (name,age,*args,city,job ): print (name,age,args,city,job)
参数组合
定义函数可以使用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,5种参数之间可以组合使用,但参数定义的顺序 必须为:必选参数、默认参数、可变参数、命名关键字参数 和关键字参数 。
1 2 3 4 def f1 (a, b, c=0 , *args, **kw ): print ('a =' , a, 'b =' , b, 'c =' , c, 'args =' , args, 'kw =' , kw) def f2 (a, b, c=0 , *, d, **kw ): print ('a =' , a, 'b =' , b, 'c =' , c, 'd =' , d, 'kw =' , kw)
练习题
以下函数允许计算两个数的乘积,请稍加改造,变成可接收一个或多个数并计算乘积:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 def mul (x, *y ): for i in y: x=i*x return x print ('mul(5) =' , mul(5 ))print ('mul(5, 6) =' , mul(5 , 6 ))print ('mul(5, 6, 7) =' , mul(5 , 6 , 7 ))print ('mul(5, 6, 7, 9) =' , mul(5 , 6 , 7 , 9 ))if mul(5 ) != 5 : print ('测试失败!' ) elif mul(5 , 6 ) != 30 : print ('测试失败!' ) elif mul(5 , 6 , 7 ) != 210 : print ('测试失败!' ) elif mul(5 , 6 , 7 , 9 ) != 1890 : print ('测试失败!' ) else : try : mul() print ('测试失败!' ) except TypeError: print ('测试成功!' ) mul(5 ) = 5 mul(5 , 6 ) = 30 mul(5 , 6 , 7 ) = 210 mul(5 , 6 , 7 , 9 ) = 1890 测试成功!
递归函数
递归函数优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出
练习题
汉诺塔 的移动可以用递归函数非常简单地实现。
请编写move(n, a, b, c)函数,它接收参数n,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import mathdef move (n, a, b, c ): if n == 1 : print (a, '-->' , c) else : move(n-1 ,a,c,b) print (a,'-->' ,c) move(n-1 ,b,a,c) move(3 , 'A' , 'B' , 'C' ) A --> C A --> B C --> B A --> C B --> A B --> C A --> C