[TOC]
<br>
### 函数的定义
>[info]函数是对程序逻辑进行结构化或过程化的一种编程方法。能将整块代码巧妙地隔离成易于管理的小块,把重复代码放在函数中而不是进行大量的拷贝。
在python中,使用关键字`def`来定义函数,格式如下:
```python
def say_hello(name):
""" 对某人打招呼
:param name: 用户名姓名
:return:
"""
print("Hello,{user}".format(user=name))
```
`def` 关键字后面紧跟着函数名称,这个实例中的函数名称就是`say_hello`。
在函数名称后,允许传入参数,参数可以是任意一种数据类型,这里实例中表示在使用say_hello函数时,需要传入一个用户名`name`,在函数内部会使用到这个`name`的变量。
定义好函数名称和参数后,使用`:`结束,换行缩进四个字符后,开始函数体,就是函数需要执行的代码块。
函数体的第一行,我们经常使用一个三引号包含的字符串,作为函数的文档说明。
文档说明不是必须的,但是写一个清晰简洁的文档说明是一个非常好的编程习惯,有很多工具可以根据文档说明直接生成接口文档哦,在使用方调用这个接口时,也能清晰知道该函数的描述信息。
### 函数的调用
以上实例,函数定义好后,当程序执行到函数定义位置时,会将函数加载到内存中储存起来,但是不会直接执行函数,需要用户明确调用才会执行函数体中的代码块。
在python中,我们使用一对圆括号来调用函数。如
```python
say_hello('Milton')
```
运行结果:
```cmd
Hello,Milton
```
能否将函数赋值给一个变量?当然可以,如下
```python
print(say_hello) # 打印函数名,可知道函数已被加载在内存中
greet=say_hello # 将函数赋值给greet
greet("Milton") # greet具有函数say_hello的功能,在greet后面跟着()就表示函数调用
```
运行结果:
```cmd
<function say_hello at 0x000002400B263E18>
Hello,Milton
```
### 函数的返回值
每个函数都会有返回值,函数返回使用关键字`return`,以上实例中没有明确return,实际上会默认返回None
```python
result=say_hello("Cherish") # 将函数的调用结果赋值给result
print(result) # 打印result就知道函数的返回值了
```
运行结果:
```cmd
None
```
在实际使用中,可能并不是简单的调用函数,在函数中打印一句话就完事了,而是希望获得某些数据返回给调用方,进行数据的使用,这时就需要在函数中使用`return`特定的内容了。
如下定义一个做加法运算的函数
```python
def add(a,b):
"""
对两个数据做加法运算,返回对应结果
:param a: 数字a
:param b: 数字b
:return: a+b 的结果值
"""
result=a+b
return result
s1=add(1,2) # 将函数返回值,赋予一个变量s1
s2=add(1,9)
print("s1 =",s1) # 打印函数返回值
print("s2 =",s2)
print("s2-s1 =",s2-s1)
```
运行结果如:
```cmd
s1 = 3
s2 = 10
s2-s1 = 7
```
### 局部变量与全局变量
函数体中的变量,属于局部变量,离开函数体后,就被销毁
函数外中的变量,属于全局变量,如果想在函数体中使用全局变量,则需要使用关键字`global` 进行声明
实例如下:
```cmd
>>> money=100
>>> percent=0.8
>>> def get_money():
... global money
... money = money - 1
... percent = 0.5
... score = 60
...
>>> get_money()
>>> money
99
>>> percent
0.8
>>> score
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'score' is not defined
>>> get_money()
>>> money
98
```
由上面示例可知,money属于全局变量,在函数get_money中,使用了`global`声明了money,说明money使用了全局的变量,在函数体中,调用一次,money就-1。
在函数中,虽然也有变量percent,变量名与全局变量名一致,但是不属于同一个变量,同理,在函数内定义了变量 score,属于局部变量,在函数外无法使用,一旦在函数外使用,则会报错:NameError: name 'score' is not defined
### 函数的参数说明
#### 位置参数
安装函数定义中的参数位置,传入对应参数值
```python
def say_hello(age,name="Milton"): # 默认值参数必须在没有默认值参数的后面,否则出错
print("Hello,{user}. I am {age} years old".format(user=name,age=age))
say_hello(18,"Cherish") # 必须按照函数定义中的参数位置,对应传入值
say_hello(28) # 第二个参数有默认值,允许不传值
```
运行结果:
```cmd
Hello,Cherish. I am 18 years old
Hello,Milton. I am 28 years old
```
#### 关键字参数
用于函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
```python
def say_hello(age,name):
print("Hello,{user}. I am {age} years old".format(user=name,age=age))
say_hello(age=16,name="Evan")
say_hello(name="Evan",age=16)
say_hello(18,name="Milton")
```
运行结果:
```cmd
Hello,Evan. I am 16 years old
Hello,Evan. I am 16 years old
Hello,Milton. I am 18 years old
```
**注意点:**
1. 关键字参数之间不存在先后顺序
2. 有位置参数时,**位置参数必须在关键字参数的前面**,如上,
`say_hello(name="Milton",18)`则会报错:SyntaxError: positional argument follows keyword argument
#### 参数默认值
为参数提供默认值,调用函数时可传可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用
```python
def say_hello(age,name="Milton"):
print("Hello,{user}. I am {age} years old".format(user=name,age=age))
say_hello(18) #调用函数时,不传入参数,则使用默认函数
say_hello(18,"Cherish") #调用函数时,传入指定参数,则使用对应参数
```
运行结果如:
```cmd
Hello,Milton. I am 18 years old
Hello,Cherish. I am 18 years old
```
#### 不定长参数
##### 包裹位置参数 - 元组(*args)
我们传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型
```python
def say_hello(*args):
print(args)
say_hello("Milton","Cherish","Evan") # 不定长位置参数传参
data=("Milton","Cherish","Evan")
say_hello(*data) # 元組解包裹传参
```
运行结果:
```cmd
('Milton', 'Cherish', 'Evan')
('Milton', 'Cherish', 'Evan')
```
##### 包裹关键字参数 -字典 (**kwargs)
kargs是一个字典(dict),收集所有关键字参数
```python
def say_hello(**kwargs):
print(kwargs)
say_hello(name="Milton",age=31,sex="M") # 不定长关键字传参
data={'name': 'Cherish', 'age': 18, 'sex': 'G'}
say_hello(**data) # 字典解包裹传参
```
运行结果:
```cmd
{'name': 'Milton', 'age': 31, 'sex': 'M'}
{'name': 'Cherish', 'age': 18, 'sex': 'G'}
```
### 匿名函数
有一种特殊的函数,叫匿名函数,它可以不用定义直接使用
在python,使用Lambda表达式,生成匿名函数
格式如:
```python
lambda 参数:操作(参数)
```
例子:
```cmd
>>> f=lambda x:x+1
>>> f(1)
2
```
lambda语句中,**冒号前是参数,可以有多个,用逗号隔开,冒号右边的是返回值**
还记得前面的加法运算函数 add(a,b) 么,这里使用lambda表达式,可以非常简洁完成。如下
```cmd
>>> f=lambda x,y:x+y
>>> f(1,3)
4
```
<hr style="margin-top:100px">
:-: ![](https://box.kancloud.cn/2ff0bc02ec938fef8b6dd7b7f16ee11d_258x258.jpg)
***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***
- 前言
- chapter01_开发环境
- chapter02_字符串的使用
- chapter03_列表的使用
- chapter04_字典的使用
- chapter05_数字的使用
- chapter06_元组的使用
- chapter07_集合的使用
- chapter08_输入输出
- chapter09_控制流程
- chapter10_实例练习_登录1
- chapter11_python函数入门
- chapter12_python中的类
- chapter13_轻松玩转python中的模块管理
- chapter14_掌握学习新模块的技巧
- chapter15_通过os模块与操作系统交互
- chapter16_子进程相关模块(subprocess)
- chapter17_时间相关模块(time & datetime)
- chapter18_序列化模块(json)
- chapter19_加密模块(hashlib)
- chapter20_文件的读与写
- chapter21_阶段考核2_登录
- chapter22_小小算法挑战(排序&二分法)
- chapter23_用多线程来搞事!
- chapter24_HTTP接口请求(requests)
- chapter25_接口测试框架(pytest)
- chapter26_阶段考核3_HTTP接口测试
- chapter27_HTML解析(pyquery)
- chapter28_阶段考核4_爬虫下载网易汽车
- chapter29_python中的那些编码坑
- chapter30_MySQL数据库操作
- chapter31 高级特性_迭代器与生成器
- chapter32 高级特性_装饰器
- chapter33 高级特性_列表处理