函数的创建和调用
1 def function_name(parameters):
2 expressions
Python 使用 def
开始函数定义,紧接着是函数名,括号内部为函数的参数,内部为函数的 具体功能实现代码,如果想要函数有返回值, 在 expressions
中的逻辑代码中用 return
返回。
举例:
公司的正常工资为每天200元,如果当月工作的天数大于等于20天,多出的天数每天按300元来结算,并且加1000全勤奖金,如果工作天数少于10天,那么所有工资按每天150元来结算,并扣除200缺勤工资。
假设该公司有4个员工,ABCD 4个员工的工作天数分别为30、25、15、5。
A = 30
B = 20
C = 10
D = 5
def getsalary(name,days):
salary = 0
if days >=20:
salary = 20 * 200 + (days-20) * 300 +1000
print('{}的工资为:'.format(name),salary)
elif days < 10:
salary = days * 150 - 200
print('{}的工资为:'.format(name),salary)
else:
salary = days * 200
print('{}的工资为:'.format(name),salary)
getsalary('A',A)
getsalary('B',B)
getsalary('C',C)
getsalary('D',D)
输出结果为:
A的工资为:
8000
B的工资为:
5000
C的工资为:
2000
D的工资为:
550
函数可以帮助我们完成更简洁的代码、减少代码的重复、易于测试、快速开发、便于团队合作。
函数的定义使用的关键字是def,定义函数的一般形式为:def
function_name():
在定义函数名字的时候我们需要注意几点:
1) 关键字不能作为函数名字。
2) 函数名中不能存在空格。
3) 函数名的首字母必须是大小写字母或者下划线。
4) 函数名的其余字母可以使用字母、数字以及下划线。
5) 不同函数名大小写不同的时候为不同函数。
采用字母+下划线+字母的形式为常用的命名方式。
调用函数
当我们创建好函数之后,如果不调用的话,不管函数中有多少print都不会执行的,因为函数就像我们买了一些工具放在仓库里,只有当我们拿出来的时候才能去使用,因此我们需要调用函数。
调用函数的时候,解释器会跳到函数体内,执行函数内的语句,当执行完毕之后回到调用的位置继续执行后续语句。
函数的参数传递
形式参数和实际参数
形式参数为我们定义函数的时候在括号中定义的参数,我们在函数的内部会使用这个参数进行代码的编写,而实际参数为函数调用的时候传进来的参数,函数返回的结果是根据这个实际参数来代替形式参数。
>>> A = 30
>>> def get_salary(days):
... salary = days * 300
... print(salary)
...
>>> get_salary(A)
9000
函数在创建的时候使用的参数days为形式参数,在我们调用函数的时候,A即为实际参数,实际要带入到函数中使用的参数。
位置参数
我们在创建函数的时候可以在括号中定义多个形式参数,我们在调用的时候,参数的数量和位置需要和创建的保持一致。
1) 参数的数量不一致
如果我们创建的函数中有2个形式参数,而我们调用的时候只使用了1个实际参数。就会出错。
>>> def get_message(address,number):
... print(address,number)
...
>>> get_message('苏州')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: get_message() missing 1 required positional argument: 'number'
2) 参数的位置不一致
当参数的位置不一致的时候会导致出现两种错误,一种是直接报错,因为我们在传参的时候会根据参数的性质而定义不同的类型,因此数据类型的错误会抛出异常。
另外一种错误是传入的参数的数据类型是对的,但是位置是错的,这样会出现错误的输出结果。
关键字参数
为了提高程序的可读性,在函数调用的时候还可以使用关键字参数调用。
通过计算容器的体积来了解关键字参数。
>>> def volume(length,width,height):
... volume = length * width * height
... print('体积为:',volume)
...
>>> volume(length=20,width=30,height=3)
体积为: 1800
使用关键字参数可以省去定义变量的过程,直接在函数调用的时候给参数进行赋值,然后传递到函数当中,最后返回结果。在这种传递方式中,参数位置的不同是不影响输出结果的。
参数默认值
当我们定义一个函数的时候,可以给函数的参数定义一个初始值,这样在我们调用函数的时候如果没有给出实际参数,那么函数会使用默认参数。
>>> def volume(length=100,width=100,height=10):
... volume = length * width * height
... print(volume)
...
>>> volume()#不给出实际参数的时候会使用默认参数100000
>>> volume(10,10,10)#给出实际参数会传递实际参数给出输出结果
1000
如果我们在创建函数的时候已经给出了默认值,那么我们在使用函数的时候如果不给出实际参数则会自动使用默认参数。
可变参数
在Python中函数的参数个数是可以变化的,也就是说参数的数量可以是不确定的,这种参数被称为可变参数。可变参数分为两种,一种是参数前加*,这种方式的可变参数在传递的时候是以元组的形式传递,一种是参数前加**,这种方式的可变参数在传递的时候以字典的形式传递。
>>> def add_number(*number):
... add_num = 0
... for i in number:
... add_num += i
... print(add_num)
...
>>> add_number(1,2,3,4,5)
15
使用可变参数的时候,这些参数会被存放在一个元组中传递到函数里,因此我们要使用这些参数的时候可以使用遍历或者索引值进行使用。
函数的返回值
我们在使用函数的过程中通常是调用函数,然后被调用的函数中的内容会依次被执行,但是我们有的时候需要的不只是执行的步骤,我们还需要获取到函数中的一些变量,因此我们在使用函数的时候还可以增添一个返回值来获取函数中的一些数据。
语法结构
返回值需要使用return语句,它的语法结构为:return
data
假如我们要使用函数来求解变量a和变量b的值,然后我们要在主函数中来输出他们的和。
def get_sum(a,b):
sum = a + b
return sum
get_sum(1,2)
如果我们把函数写成上面的模式然后输出是不会有输出结果的,因为我们返回了sum,等同于get_sum(1,2)这一部分的值是sum,但是并没有对它进行操作,如果我们修改一下代码:
def get_sum(a,b):
sum = a + b
print('调用了这个函数')
return sum
print('完成返回值的传递')
s = get_sum(1,2)
print(s)
输出结果为:
调用了这个函数
3
使用这种方式理解一下,在语句s = get_sum(1,2)中,先是调用了这个函数,然后函数顺序往下执行,到了return语句之后,把函数的值等同于sum,然后返回之后后面的语句就不再执行。返回值之后s就可以进行赋值操作,把函数的返回值赋给s,然后输出就可以看到我们的输出结果。
def test():
data = '局部变量'
print('在函数内部输出data为:',data)
test()
print('在主程序中输出data:',data)
输出结果为:
在函数内部输出data为: 局部变量
Traceback (most recent call last):
File "C:/Users/轻烟/PycharmProjects/untitled/venv/Include/ts.py", line 6, in <module>
print('在主程序中输出data:',data)
NameError: name 'data' is not defined
由于变量data是在函数内部定义的,我们在主程序中使用变量data则会出现访问的变量不存在的问题,所以我们要注意在函数内部定义的变量为局部变量,未作特别声明的话是不可以在函数外使用的。
2. 全局变量
全局变量我们也可以从字面意思中理解到它就是作用在全局的变量,有的人可能自然而然的认为那么全局变量一定是定义在主程序中的变量了,其实全局变量也是可以作用在函数中的,在这里我们来介绍两种全局变量的使用方式:
data = '全局变量data'
def test():
print('这是作用在函数中的全局变量:',data)
test()
print('这是作用在函数外的全局变量:',data)
输出结果:
这是作用在函数中的全局变量: 全局变量data
这是作用在函数外的全局变量: 全局变量data
这种方式就是我们通常情况下使用的全局变量,我们在主程序中定义的变量可以在函数内部直接的进行使用。
2) 使用global关键字
我们在函数内定义的变量也可以编程全局变量,这时候我们就要使用到global关键字。 首先我们先看一下当全局变量和局部变量的名字相同的时候会是一个怎么样的情况。
data = '这里是全局变量data'
print(data)
def test():
data = '这里是局部变量data'
print(data)
test()
print('再检查一下全局变量data:',data)
输出结果为:
这里是全局变量data
这里是局部变量data
再检查一下全局变量data: 这里是全局变量data
通过这里例子我们可以看出全局变量和局部变量的命名相同的时候是不影响全局变量的内容的,但是如果我们想要在函数中修改全局变量的值,那么我们就要使用global关键字。
data = '这里是全局变量data'
print(data)
def test():
global data
data = '这里是局部变量data'
print(data)
test()
print('再检查一下全局变量data:',data)
输出结果为:
这里是全局变量data
这里是局部变量data
再检查一下全局变量data: 这里是局部变量data
通过global关键字,在局部中声明告诉这个函数global是一个全局变量,那么修改了之后,全局中的变量都做了修改,global关键字就是可以使一个变量变成全局变量。
当全局中没有声明变量的时候,我们在局部中也可以使用global关键字直接来声明一个变量是全局变量,那么我们在函数中定义的变量在主程序中也是可以使用的
def test():
global data
data = '这是在局部创建的变量data'
print('这是在函数中输出:',data)
test()
print('这是在主程序中输出:',data)
输出为:
这是在函数中输出: 这是在局部创建的变量data
这是在主程序中输出: 这是在局部创建的变量data
在写程序的时候尽量避免全局变量和局部变量的名字一致,尽管他们作用于不同的区域,但是会影响对代码的理解。
匿名函数
我们在写程序的过程中有时不需要给函数命名,这时候就可以使用匿名函数,我们在Python中使用lambda表达式来使用匿名函数。
匿名函数的定义
变量m为我们输入的值,我们需要采用匿名函数来返回m的平方和,也就是输入2要返回值为4。
m = int(input('请输入一个数字:'))#m为输入的值
a = lambda x : x * x #使用变量a来构成一个表达式
print('返回值为:',a(m))
输出结果为:
my_list = [('元组甲',15,33),('元组乙',25,26),('元组丙',7,7)]
my_list.sort(key=lambda x : x [2] - x[1])#使用key关键字来引入排序方式,排序方式根据第三个元素减去第二个元素的差值,对应索引为2和1
print(my_list)
输出结构为:
[(
'元组丙'
,
7
,
7
), (
'元组乙'
,
25
,
26
), (
'元组甲'
,
15
,
33
)]
我们可以先简单的计算一下,他们的差值分别为18、1、0,所以他们的排列顺序应该为丙、乙、甲,通过lambda表达式中的返回结果x[2]-x[1],我们获得了他们的差值,然后根据差值进行排序。
三大基础函数
在Python中有三个基础函数,分别是filter()、map()和reduce(),他们分别为我们提供过滤、映射和聚合的功能。
filter()函数
在数据筛选和过滤的时候我们通常会采用filter()函数帮助我们快速的解决问题,它的语法格式为:
filter
(函数,可迭代对象)
在filter函数中,前面放我们的过滤或筛选方式,即函数名,后面存放可迭代的对象,我们看下面的例子:
def test(x):
if x % 2 == 0:
return x
my_list = [1,2,3,4,5,6]
print(filter(test,my_list))#只需要写函数名即可,不用加参数
输出结果:<
filter
object
at
0x034C2DD8
>
关于这个例子,我们首先定义了一个test()函数,如果x是偶数则返回其值,然后通过filter()函数使用test()函数来过滤my_list列表,但是输出结果却是<filter object at 0x034C2DD8>,在这里我们需要注意filter()函数的返回值为一个可迭代的对象,我们需要通过迭代的方式访问其中的值,或者使用列表list()函数强制类型转换。
def test(x):
if x % 2 == 0:
return x
my_list = [1,2,3,4,5,6]
print(filter(test,my_list))
for i in filter(test,my_list):
print('迭代后中的数据:',i)
print('使用list()方法:',list(filter(test,my_list)))
输出结果为:
迭代后中的数据: 2
迭代后中的数据: 4
迭代后中的数据: 6
使用list()方法: [2, 4, 6]
map()函数
在前面我们曾多次使用到过map()函数,例如我们在输入多个值的时候,我们会采用map()函数,我们需要输入四个值的时候:
a,b,c,d = map(int,input().split())
print(a,b,c,d)
map()函数的语法格式为:
map(函数,可迭代对象)
在使用map()函数的时候,我们大多用于对数据的处理,把可迭代对象中的数据经过函数处理之后存储,我们在存储的时候继续采用list()函数进行存储。
我们先看上面输入四个值的例子,int为函数,input().splite输入的值为可迭代的对象,经过int函数的处理后存放在map对象当中。
我们可以通过map()函数将一个序列中的所有数据通过一个函数进行处理。
举例: 我们在一个列表中存放了一下字母,如果存在小写字母,那么将它变成大写字母。
代码如下:
def test(x):
if x.islower():
return x.upper()
else:
return x
my_list = ['d','o','t','C','p','P']
print(list(map(test,my_list)))
输出结果为:
['D', 'O', 'T', 'C', 'P', 'P']
test()函数中会先对x进行判断,如果是小写字母就返回它的大写字母,如果不是小写字母就返回它的值。
reduce()函数
reduce()函数用于把可迭代的对象通过函数方法进行聚合。
语法格式为:reduce
(函数, 可迭代对象[, 初始值])
我们已知一个列表为[1,2,3,4],我们需要求列表里所有项依次相乘的值,可以使用reduce()函数。
其实这种方式的求解是比较浪费时间的,因为需要进行迭代的次数太多,我们还可以采用空间替代时间的方式来求解这个问题。
代码如下:
n = int(input("输入需要得到的项数:"))
fibonacci = [1,1]
for i in range(2,n):
fibonacci.append(fibonacci[i-1] + fibonacci[i-2])
print('对应值为',fibonacci[n-1])
输出结果为:
输入需要得到的项数:
4
对应值为
3
这种方式我们首先给列表规定了前2项的值,然后对于我们要求解的项数n,我们直接通过公式把这个斐波那契数列的列表填充到我们需要的那一项,最后根据索引值直接找到对应项输出结果。
内置函数
abs() | 返回绝对值 |
bin() | 返回二进制 |
bool() | 返回布尔值 |
chr() | 用一个范围在256内的整数作参数,返回一个对应的字符 |
cmp(x,y) | 用于比较,前者大于后者返回1,相等返回0,小于后者返回-1 |
compile() | 将字符串便以为字节代码 |
complex() | 创建一个复数 |
dict() | 创建字典 |
divmod(x,y) | 返回一组值,前者为x和y的商,后者为余数 |
enumerate() | 返回序列中元素及其索引值,使用for循环可依次输出。 |
eval() | 返回字符串表达式的值 |
file() | 创建一个 file 对象 |
filter() | 过滤函数 |
float() | 把整数和字符串转换成浮点数 |
format() | 格式化函数 |
getattr() | 返回一个对象属性值 |
globals() | 全局变量 |
hash() | 返回一个对象的哈希值 |
help() | 查看函数或者模块的功能 |
hex() | 将10进制整数转换成16进制 |
id() | 返回一个对象在内存中的地址 |
input() | 标准输入 |
isinstance() | 判断一个对象是否为已知的类型 |
int() | 把字符串或数字转换为整型 |
len() | 返回序列的长度 |
list() | 把其他数据类型转换为列表 |
locals() | 返回当前位置的所有局部变量 |
long() | 把一个数字或字符串转换为长整型 |
map() | 映射函数 |
max() | 返回最大值 |
min() | 返回最小值 |
next() | 返回迭代对象的下一项 |
oct() | 整数转换八进制数 |
pow(x,y) | 返回x的y次方 |
print() | 输出 |
range() | 创建整数序列 |
reduce() | 聚合函数 |
reload() | 重载模块 |
reverse() | 逆序 |
round() | 对浮点数四舍五入 |
set() | 创建集合 |
sorted() | 排序 |
sum() | 求和 |
zip() | 将可迭代的多个对象中根据对应关系组合在一个元组中 |