python函数基础

函数

什么是函数

函数就是功能的封装,将一组语句通过一个函数名封装起来。要想执行这个函数,调用其函数名即可。

函数的特性:

  • 减少重复代码
  • 可扩展性强
  • 代码易维护

函数的定义

python使用关键字def定义一个函数,后面跟函数名。要想调用这个函数,函数名+()就可以完成调用。

1
2
3
4
5
6
def func():
print('函数的定义')


# 调用函数
func()

函数的参数

形参

形式上定义的参数,只有在函数调用的时候才分配内存单元,只在函数内部有效。函数调用结束则形参失效。

实参

实际传入的参数,可以是常量、变量、表达式、函数等、无论是何种类型的值,在进行函数调用的时候必须要有确定的值,实参是要传给形参。

比如说:

1
2
3
4
5
6
7
8
9
10
11
def calc(x,y):
"""
计算两个数的和的函数
:param x:形参 x
:param y:形参 y
"""
res = x + y
return res


print(calc(10, 10)) # 传入两个实参,调用函数获取计算结果

位置参数

根据形参,传入的参数一一对应,按照顺序传入,叫做位置参数。

默认参数

先写一个打印学生信息的函数,传入的参数为姓名、年龄、性别、班级。

1
2
3
4
5
6
7
8
def students(name, age, sex, classes):
print('学生姓名:{0};年龄:{1};性别:{2};班级:{3}'.format(name, age, sex, classes))


students('江子牙', 21, '男', 'Python1期')
students('江xx', 19, '女', 'Python1期')
students('江yy', 15, '不男不女', 'Python1期')
students('子 牙', 25, '男', 'Python1期')

可以看出我们写了重复代码(参数Python1期),python语言有个默认参数可以解决此问题。

1
2
3
4
5
6
7
8
def students(name, age, sex, classes='Python1期'):
print('学生姓名:{0};年龄:{1};性别:{2};班级:{3}'.format(name, age, sex, classes))


students('江子牙', 21, '男', )
students('江xx', 19, '女', )
students('江yy', 15, '不男不女', )
students('子 牙', 25, '男', 'Python2期')

没有传值则是默认的值,传入了值的就会是这个值。

关键字参数

正常情况下,传参数要一一对应,形参也一一对应值。但是如果不想按顺序,就可以是关键字参数。但是,关键字必须放在位置参数后面。

1
2
3
4
5
6
7
8
9
10
def stu_info(name,age,course='高三一班'):
print('-----学生信息-----')
print('姓名:',name)
print('年龄:',age)
print('课程:',course)


# 传入的参数可以先传age,不一定要根据形参的顺序。这就是关键字参数传参。
stu_info(age=199,course='大学啦',name='小天文')
stu_info(age=20,name='文帅')

非固定参数

当传入的参数个数不确定的情况下,就可以使用非固定参数,也叫做不定长参数。

args

*args 实际上是接收的一个元祖,打包所有不固定参数。

1
2
3
4
5
6
7
8
9
10
11
def send(msg, *args):
print('固定参数', msg)
print('所有非固定参数', args)
for i in args:
print('我是非固定参数', i)
print('------------------')


send('别浪了……', 'a')
send('别浪了……', 'a', 'b', 'c')
send('别浪了……', ['a', 'b', 'c'])

执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
固定参数 别浪了……
所有非固定参数 ('a',)
我是非固定参数 a
------------------
固定参数 别浪了……
所有非固定参数 ('a', 'b', 'c')
我是非固定参数 a
我是非固定参数 b
我是非固定参数 c
------------------
固定参数 别浪了……
所有非固定参数 (['a', 'b', 'c'],)
我是非固定参数 ['a', 'b', 'c']
------------------

可以发现,当我们传入一个列表的时候,会把它当作一个整体接收。如果我们只是想把列表的元素一个个作为参数传入,而不是一个整体的时候,可以这样:

1
2
3
4
5
6
7
8
9
def send(msg, *args):
print('固定参数', msg)
print('所有非固定参数', args)
for i in args:
print('我是非固定参数', i)
print('------------------')


send('分开传吧...', *['a', 'b', 'c', 'd'])

执行结果:

1
2
3
4
5
6
7
固定参数 分开传吧...
所有非固定参数 ('a', 'b', 'c', 'd')
我是非固定参数 a
我是非固定参数 b
我是非固定参数 c
我是非固定参数 d
------------------
kwargs

当我们传入的参数不固定,又想通过关键字参数的方式传入的时候,python语言有个**kwargs可以接收。

**kwargs接收的实际上一个字典。

1
2
3
4
5
6
7
8
9
10
11
def info(name, age, **kwargs):
print('固定参数:', name, age)
print('所有不固定参数:', kwargs)
for k, v in kwargs.items():
print(k, v)
print('------------------------------')


info('111', 222, sex='男', money=9.9)
# 同样,想通过一个整体传入多个关键字参数时,可以构造成一个字典,前面加**
info('111', 222, **{'sex': '变态', 'money': 100, 'mobile': 13006293101})

执行结果:

1
2
3
4
5
6
7
8
9
10
11
固定参数: 111 222
所有不固定参数: {'sex': '男', 'money': 9.9}
sex 男
money 9.9
------------------------------
固定参数: 111 222
所有不固定参数: {'sex': '变态', 'money': 100, 'mobile': 13006293101}
sex 变态
money 100
mobile 13006293101
------------------------------

注意

args、kwargs只是名称,不一定要以它为名,约定成俗而已。

比如:

1
2
3
4
5
6
7
8
9
10
def info(name, age, **k):
print('固定参数:', name, age)
print('所有不固定参数:', k)
for k, v in k.items():
print(k, v)
print('------------------------------')


info('111', 222, sex='男', money=9.9)
info('111', 222, **{'sex': '变态', 'money': 100, 'mobile': 13006293101})

函数的返回值

python语言中,用return关键字表示函数返回。它具有以下含义:

  • 函数外部的代码想要获取函数内部执行的结果,就用return把结果返回。
  • 代表函数的执行结束,并返回结果,如果函数没有指定return,返回值默认为None
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def calc(x, y):
    """
    计算两个数的和的函数
    :param x:形参 x
    :param y:形参 y
    """
    res = x + y
    return res


    print('函数执行的结果:',calc(10, 10))

全局和局部变量

  • 在函数内部定义的变量成为局部变量,在程序一开始定义的变量称为全局变量。
  • 全局变量的作用域是整个程序,局部变量的作用域是定义该变量的函数。
  • 当全局变量和局部变量重名时,在函数内,局部变量优先。在其余地方,全局变量优先。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    name = 'Black girl'     # 全局变量

    def change_name():
    name = '黑色姑娘' # 局部变量,定义在函数里面的变量,函数一旦执行完毕,则释放局部变量,如果里面没有定义,则使用外面的,
    print(name) # 黑色姑娘--->如果加global,就可以使用全局变量


    change_name()
    print(name) # Black girl 修改局部变量并不影响全局变量的值,作用域不一样。
    执行结果:
1
2
黑色姑娘
Black girl

定义了一个change_name的函数。接着调用了这个函数,因为这个函数内部定义了一个局部变量黑色姑娘。函数体内执行print的时候,是黑色姑娘。函数调用完成之后,程序又执行力一个print。这个时候。外面的Black girl是全局变量,并不会收到函数内部定义的同一个变量名name的影响,所以打印的是Black girl

再看一个函数里嵌套函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 全局变量18
age = 18

def func1():
局部变量73
age = 73
print('alex')

def func2():
print('egon')
print(age)

return func2


# 调用func1,返回来一个func
res = func1()
# 所以可以通过返回值加()调用
res()
print(age)

执行结果:

1
2
3
4
alex
egon
73
18

其他函数

嵌套函数

在函数内部再定义一个函数就是嵌套函数。

当外部函数调用内部函数的时候,内部函数会拥有外部函数的作用域与参数。形成了闭包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
age = 19


def f1():
def f2():
print(age)

age = 73
# 调用内部函数
f2()


f1()
print(age)

匿名函数

特点:

  • 没有函数名,也没有代码块。
  • 一行代码,没有名字,用关键字lambda声明
  • 主要用于和一些函数搭配使用:内置的map()filter()reduce()、…
  • 节省代码量
    1
    res = map(lambda x,y:x+y,[1,2,3])

高阶函数(满足其一就是高阶函数)

  • 函数可以接收一个函数作为参数传入
  • 函数的返回值是一个函数
/