Python 基础三

Python 函数

知识要点

1、函数的简介

如果在开发过程中,需要某块代码多次,为了提高编写效率以及代码重用,所以把具有独立功能的代码块组建为一个小模块,这就是函数。python中提供了许多内建函数,如print()。用户可以自定义函数。

例如:计算圆的面积 S = $\pi r ^2$

1
2
3
4
5
6
r1 = 12.34
r2 = 9.08
r3 = 73.1
s1 = 3.14 * r1 * r1
s2 = 3.14 * r2 * r2
s3 = 3.14 * r3 * r3

2、函数的定义和调用

(1) 定义函数

定义函数格式如下:

1
2
3
4
5
6
7
def 函数名(参数[可选]):
功能性的代码
# 定义一个函数,能够完成打印信息的功能
def printInfo():
print('----------------------------')
print(' 人生苦短,我用Python ')
print('----------------------------')

(2) 调用函数

定义函数滞后,相当于有了一个具有某种功能的代码,想要让这些代码能够执行,需要调用它,调用函数很简单,通过 函数名() 即可完成调用。

1
2
# 定义函数后,函数不会自动执行,需要调用它才可以
printInfo()

(3) 注意:

  • 每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了
  • 如果函数中执行了 return 也会结束函数

3、函数的文档说明

1
2
3
4
5
6
7
8
9
10
11
12
def test(a,b):
'''求两个数的和'''
print("%d" %(a+b))
test(11,12)
help(test) # 也可以用 print(test.__doc__)

结果:
23
Help on function test in module __main__:

test(a, b)
求两个数的和

4、函数的参数

Python 的函数定义非常简单,但灵活度非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使用函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。

1、位置参数

我们先写一个计算 x^2 的函数:

1
2
def power (x):
return x*x

对于 power() 函数,参数 x 就会一个位置参数。

当调用 power 函数时,必须传入且仅有一个参数 x

1
2
3
4
power(5)
25
power(25)
225

现在,如果我们要计算 $x^3$ 怎么办?可以再定义一个 power3 函数,但是如果要计算 X^4, X^5……怎么办?我们不能定义无限多个函数。

定义 power(x,n)

1
2
3
4
5
6
def power(x,n):
s = 1
while n>0:
n = n-1
s = s*x
return s

对于这个修改后的 power(x,n) 函数,可以计算 n 次方

1
2
3
4
power(5,2)
25
power(5,3)
125

修改后的 power(x,n) 函数有两个参数:x , n ,这两个参数都是位置参数,调用函数时,传入的两个值按照位置顺序赋值给 x 和 n 。

2、默认参数

新的 power(x,n)函数定义没有问题,但是就得代买失效了,原因是我们增加了一个参数,导致就得代码缺少一个参数而无法正常调用:

1
2
power(5)
报错:缺少一个位置参数 n

这个时候,就要使用默认参数进行定义,

1
2
3
4
5
6
def power(x,n=2):
s = 1
while n>1:
n = n - 1
s = s * x
return s

这样,当我们调用 power(5) 时,就会默认为 power(5,2)

以上例子可以看出,默认参数可以简化函数调用。设置默认参数时要注意

  • 必选参数在前,默认参数在后,或者都是默认参数,否则报错
  • 当函数有多个参数时,把变化大的参数放在前面,变化小的参数放在后面,变化小的参数可以作为默认参数。

3、使用默认参数的好处

例子:小学生注册的函数,需要传入 name 和 gender 两个参数:

1
2
3
def enroll(name,gender):
print('name:',name)
print('gender:',gender)

这样调用 enroll() 函数只需要传入两个参数

1
2
3
4
5
enroll('Sarah','F')

结果:
name:Sarah
gender:F

如果要继续传入年龄、城市信息怎么办,这样会使得调用函数的复杂度加大

我们可以吧年龄和城市设为默认参数

1
2
3
4
5
def enroll(name,gender,age=6,city="Beijing")
print('name:',name)
print('gender:',gender)
print('age:',age)
print('city:',city)

这样大多数学生在注册时不需要再提供年龄和城市,只需要两个参数

1
2
3
4
5
6
7
enroll('Sarah','F')

结果:
name:Sarah
gender:F
age:6
city:Beijing

只有与默认参数不符合的学生才需要额外提供信息

1
2
enroll('Bob','M',7)
enroll('Adam','M',city='Tianjing')

可见,默认参数降低了函数调用难度,而一旦需要复杂调用时,又可以传递更多的参数来实现。意思是,除了 name ,gender 两个参数外,最后一个参数应用在 age city参数由于没有提供,任然是默认值。

也可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如 enroll(‘Adam’,’M’,city=’Tianjing’) city 参数时传进去的,其他为默认值。

注意:默认参数有个大坑,如下

先定义一个函数,传入一个list,添加一个END 再返回:

1
2
3
def add_end(L=[]):
L.append('END')
return L

结果似乎不错

1
2
3
4
add_end([1,2,3])
[1,2,3,'END']
add_end(['x','y','z'])
['x','y','z','END']

使用默认参数调用时,开始结果是对的

1
2
add_end()
['END']

但是,再次调用就出问题了:

1
2
3
4
add_end()
['END','END']
add_end()
['END','END','END']

解释:Python函数在定义的时候,默认参数L的值就被计算出来了,即[], 因为默认L 也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,默认的呢绒就变了,不再是函数定义时的[]了。

  • 默认参数必须指向不变对象
1
2
3
4
5
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L

那么无论调用多少次都没问题了。

str,None 这样的不变对象,对象内部数据不能修改,可以减少由于修改数据导致的错误。此外,由于对象不变,多任务环境下读取对象不需要加锁,同时读取一点问题没有。如果可以设计一个不变对象,尽量设计成不变对象。

4、可变参数[list 或 tuple]

在pyrhon 中还可以定义可变参数。传入的参数个数是可变的

1
2
3
4
5
6
7
8
9
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n*n
return sum

结果:
calc(1,2)
5
1
2
3
4
# 如果已经有了一个list 或tuple
nums = [1,2,3]
calc(nums[0],nums[1],nums[2])
calc(*nums) # 简便写法

5、命名关键字参数[字典]

对于关键字参数,调用者可以传入任意个不受限制的关键字参数

1
2
3
4
5
6
7
def person(name,age,**kw):
if 'city' in kw:
pass
if 'job' in kw:
pass
print('name:',name,'age:',age,'other:',kw)
person('Jack',24,city='Beijing',addr='Chaoyang',zipcode=13728)

6、参数组合

在python中,必选参数、默认参数、可变参数、关键字参数、命名关键字参数。组合使用也是可以的,但是必须按照以上的殊勋。

5、函数返回值

return

一个函数有多个返回:

1
2
3
4
5
6
def divid(a,b):
shang = a/b
yushu = a%n
return shang,yushu # 默认元组
result = divid(5,2)
print(result)

6、递归函数

函数内部,自己调用自己

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 递归(自己调用自己)
# 5!= 5*4*3*2*1 --> 5*4!
# 4!= 4*3*2*1 4*3!
# 3!= 3*2*1
# 2!= 2*1
# 1!= 1
# show()就是算一个数的阶乘
def show(num):
# result = 5 * 4!
if num == 1:
return 1
else:
return num * show(num-1)


result = show(6)
print(result)

7、局部变量

  • 局部变量:在函数内部定义的函数
  • 作用范围在这个函数内部。
  • 作用:为了零时保存数据需要在函数定义变量来进行存储
  • 当函数调用时,局部变量呗创建,当函数调用完成后这个变量就不能用了

8、全局变量

一个变量既能在一个函数中使用,也能在其他函数中使用,全局变量

在函数外定义的变量就是全局变量

全局变量能够在所有函数中进行访问

  • 当函数内出现局部变量和全局变量重名时,函数内部的 变量名 = 数据 可以理解为一个局部变量而不能修改全局变量。
  • 修改全局变量 globle XX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 局部变量和全局变量: 在函数里面的定义的变量就是局部,外面就是全局

# 全局变量,可以在函数内部使用(前提是函数内部没有跟全局变量重名的变量)
g_age= 20

def show():
# 局部变量
# global age # 函数内部想要修改全局变量的值的时候使用
age = 18
print(age)
show()

print(age)
# 提示: 以后不要把全局变量和局部变量的名字设置成一样
感谢您的阅读,本文由 LEE 版权所有。如若转载,请注明出处:LEE(https://ChubbyLEE-Math.github.io/2020/07/07/python%20%E5%9F%BA%E7%A1%80%E4%B8%89/
Python 基础二
Python 基础四