Python函数

1.调用函数:

abs(x)			#返回x的绝对值
max(x,y,z)		#返回最大值

数据类型转换:

int(X)
float(X)
str(X)

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:

a=abs
print(a(-5))

======================
2.定义一个函数:

def my_Function(x):
	if x>0:
		return x
	else:
		return -x
		
print(my_Function(-88))			#调用函数

pass
pass语句指什么也不做,先把代码执行起来再说。pass还可以用在其他语法中

def my_Function(x)
	pass

返回多个值
函数可以返回多个值吗?答案是肯定的。

x, y = move(100, 100, 60, math.pi / 6)
print(x, y)
151.96152422706632 70.0

但其实这只是一种假象,Python函数返回的仍然是单一值:

r = move(100, 100, 60, math.pi / 6)
print®
(151.96152422706632, 70.0)

原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

注意:函数要是没有return值,默认return None

======================
3.函数的参数

def power(a,b):			#返回a的b次方
	s=1
	while b>0:
		s=s*a
		b=b-1
	return s

print(power(2,10))

当然了,如果你传入的参数是power(2),这样函数就缺少了参数,报错。pythone可以写默认参数,写法:

 def power(a,b=10):			#返回a的b次方,若是缺少参数b,默认返回a的10次方
    	s=1
    	while b>0:
    		s=s*a
    		b=b-1
    	return s

我们来测试一下:
在这里插入图片描述
默认参数的定义和使用
从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注意:

一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。

当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。

使用默认参数有什么好处?最大的好处是能降低调用函数的难度。

可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如一个函数是:

def enroll(name,gender='Female',age=21,city='ZheJiang'):

调用enroll('Adam', 'M', city='Tianjin'),意思是,city参数用传进去的值,其他默认参数继续使用默认值。

默认参数很有用,但使用不当,也会掉坑里。默认参数有个最大的坑,演示如下:

def add_end(L=[]):
	L.append('end')
	return L

print(add_end())
print(add_end())

在这里插入图片描述
第一个end是对的,但第二次又执行了end就不是我们想要的效果了。它仿佛记住了list L

注意:定义默认参数要牢记一点:默认参数必须指向不变对象!
所以,代码用默认参数None就没有错了,None是一个不变的对象

在这里插入图片描述

为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁(线程锁),同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

======================
可变参数

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

但是调用的时候,需要先组装出一个list或tuple:

 calc([1, 2, 3])

 calc((1, 3, 5, 7))

如果用可变参数的话,可以这样调用:

calc(1,2,3)
calc(1,3,5,7)

代码写法需要改成可变参数:

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

如果已经有了一个list,那要怎么传入呢?

nums=[1,2,3]
需要这样书写:calc(nums[0],num[1],num[2])
因为代码已经改成可变参数传入,这时候传入一个nums显然会出错

======================
关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装成一个tuple而关键字参数允许你传入人一个含参数名的参数,这些关键字参数在函数内部自动组装成一个dict。

def info(name,age,**other):
	print(name,age,other)

dic={'city':'Zj','hobby':'sport'}
info('FJY','21',**dic)

要注意的是,参数设定为关键字参数,传入的参数也要相对应。

=====================
参数组合

我们学过了必选参数,默认参数,可变参数和自定义参数,当它们同时出现在一个函数里时,参数的顺序必须是:必选参数,默认参数,可变参数,自定义参数。比如:

def func(name,age=21,*money,**hobby):
	print(name,age,money,hobby)
	
m=(1,2,3,4,5)
h={'hobby':'sport','hobby':'japanese'}
func('fjy',22,*m,**h)

============================
4.递归函数

在函数内部,可以调用其他函数,但一个函数在内部调用本身,这个函数就是递归函数。举个例子:计算n的阶乘

def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

如果我们计算fact(5),可以根据函数定义看到计算过程如下:

===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。(我感觉还是循环看的舒服…)

递归函数是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致上溢(溢出)不信可以试试fact(100000),
在这里插入图片描述

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环一样,所以把循环看成是一种特殊的尾递归函数也是可以的。

尾递归是指,在函数由于return n*fact(n-1) 引入乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是把每一步的乘积传入到递归函数中:

<!-- 还没写完,下次继续。。。-- >
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值