函数是什么?
函数是由一些组织好的,可重复使用的,用于实现某一特定功能的代码块。
函数的出现是为了使编程时代码更为简洁,提高程序的可读性、应用性等。
函数分为系统内建函数和用户自定义函数,如 print() 就是系统内建函数。
函数定义格式
自定义一个函数用于实现自己想要的功能,基本语法如下:
def functionname(parameters):
"函数_说明字符串"
function_suite
return [expression]
函数以 def
关键词开头,接着是函数名称和圆括号()
,再接着是一个冒号 :
,这样就完成了一个函数的简单声明。紧接着下方就是函数体,是函数真正要封装(执行)的内容,函数体内的代码必须使用相同的缩进(一般是4空格)。
- functionname:为函数名称,由用户自定义,但不应与已有函数重名。
- parameters:为传递参数,这里称为“形式参数”,当需要传入参数到函数内部时通多这里进行定义,数量不限;没有参数传递时可省略不用。
- function_suite:为要实现功能的代码块,各代码块将要遵循缩进原则!
- return:为返回语句,用于返回一个或多个参数,该语句为可选语句。
- expression:为要返回的参数,它可以是任意类型,当缺省时默认返回 None
Python 函数没有结束符一说,它是通过代码缩进关系来确定函数关系的,一般在函数定义结束后会腾出一行空行。
无参数函数定义
实例:
def display():
print("hello world")
函数调用
当我们定义好一个函数体后,我们就可以通过其函数名称进行调用,具体如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def display():
print("hello world")
display() # 调用函数
运行输出:
hello world
带参数函数定义
定义带参数函数体时,可以在括号内声明一个或多个的传入参数(称为“形式参数”),参数之间用逗号 ,
隔开;而在调用函数时同样需要传入相应个数的参数(称为“实际参数”),用于将形式参数替换为实际的值,传入的实际参数之间同样用逗号 ,
隔开。
实例如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def display ( str ): # 定义一个传入参数str
print("传入参数:", str)
display("这是一个自定义函数") # 调用函数
运行输出:
传入参数: 这是一个自定义函数
说明:实例用在调用函数时,用实际的参数 “这是一个自定义函数” 替换 形式参数“ str ”,最后传入函数内给 print() 输出显示。
函数参数
在定义带参数函数时,都需要传入相应的参数。
函数参数可以支持以下类型:关键字参数、默认参数、不定长参数...
必备参数
必备参数:是指在定义带参数函数时,在后面的函数调用中,用户必须传入参数,而且传入的参数必须与定义的形参个数一致,否则程序将报错。
实例如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def personal_info( name ):
print("name:", name)
personal_info("小明") # 传入参数,程序正常执行
personal_info() # 不传入参数,程序将报错,并终止执行
实例输出:
name: 小明
Traceback (most recent call last):
File "C:\Users\QinTaiW\Desktop\aaa.py", line 8, in
personal_info( ) # 不传入参数,程序将报错,并终止执行
TypeError: personal_info() missing 1 required positional argument: 'name'
可见程序在执行到第二次调用函数时,由于没有传入必须的参数,所以程序报错并停止往下执行了。
同样的,当传入的实际参数比定义时的形式参数要多时,程序同样会报错和终止。同学们可以去尝试一下。
关键字参数
定义带参数函数,在调用函数必须传入相应的参数,否则解析器会报错,程序执行中断。
调用函数时,使用关键字方式赋值时,实参与形参无顺序关系,只根据关键字进行对应赋值。
实例如下:
#! /usr/bin/python3
# -*- coding: utf-8 -*-
def personal_info( name, age ):
print("name:", name, "age:",age)
# 按顺序赋值(与顺序有关)
personal_info("小明",25)
personal_info(25, "小明")
# 按关键字赋值(与顺序无关)
personal_info(name="小明", age=25)
personal_info(age=25, name="小明")
运行输出:
name: 小明 age: 25
name: 25 age: 小明
name: 小明 age: 25
name: 小明 age: 25
可见调用函数时,直接赋值方式:实参与形参之间的传递方式是按顺序依次进行赋值的;按关键字方式赋值:实参与形参之间无顺序关系,它们之间只根据各自之间的关键字进行对应赋值。
注:不管是使用顺序方式赋值,还是关键字方式赋值,传入的实参个数必须与函数中定义的形参个数一致,不然程序将报错。
默认参数
默认参数:是指用户在自定义函数时,已给形参绑定了一个参数,该称为默认参数。
默认参数特点:已绑定了默认参数的函数,在调用函数时,可缺省该参数的传入,如果缺省该参数,函数执行时,则使用默认值;当不缺省该参数时,后面传入的实际参数将替代默认参数。
注意:没有绑定默认值的参数,在调用函数时,必须传入对应的值。
#! /usr/bin/python3
# -*- coding: utf-8 -*-
def personal_info( name, age=20 ): # 绑定默认值
print("name:", name, "age:",age)
personal_info(name="小明") # 缺省 age 参数
personal_info(name="小明", age=25) # 刷新 age 的值
实例输出:
name: 小明 age: 20
name: 小明 age: 25
可见使用默认参数的函数,在缺省实参时,程序执行中并不会报错,而是使用了定义函数时的默认值。
不定长参数
不定长参数的出现是为了满足,在定义函数后,可能因某些情况,在后面使用中需要一些输入的实参比定义前的形参要多。换句话来说就是,函数能处理比当初声明时更多的参数,这些参数称为不定长参数,常见的是传入一个列表、元组、字典 等类型的数据。
不定长参数使用 *
星号 或 **
双星号来声明:
- 【* 号不定长参数】:用于接收参数为 列表、元组... 迭代数据,冗余的数据将被存入一个 元组 当中。
- 【 号不定长参数】:用于接收参数为 字典型 数据,冗余的数据将被存入一个 字典** 当中。
【* 号不定长参数】
在定义形参时,在形参的前面添加一个 *
号,表示可接收不定长参数,多余的参数将被存入一个元组中。实例如下:
实例1:
#! /usr/bin/python3
# ! -*- coding: utf-8 -*-
def custom_print(*aa):
print(type(aa)) # 查看 aa 当前的类型
print(aa) # 输出显示 aa
custom_print("Python", "hello", "world")
输出如下:
('Python', 'hello', 'world')
分析:可见多余的参数都被接收到新的元组当中。
实例2:
功能:定义不定长参数,并一次赋予多个值。
#! /usr/bin/python3
# ! -*- coding: utf-8 -*-
def student_info(name, sex, subject, *score):
print("name:", name, "sex:", sex)
print("subject:", subject, "score:", score)
# 调用函数
student_info("小明", "男", "语文", 80, 92, 85, 87, 79, 82, 72)
输出如下:
name: 小明 sex: 男
subject: 语文 score: (80, 92, 85, 87, 79, 82, 72)
分析:调用函数时,函数中的实参依次赋值给形参,后面多余的参数全部由不定长参数*score接收下来,数据为元组类型。
实例3:
功能:输入一个不定长参数,求不定长参数里面的最大值。
#! /usr/bin/python3
# -*- coding: utf-8 -*-
def student_info(name, sex, subject,*score): # 定义不定长参数 score
print("name:",name, "sex:",sex)
print("subject:",subject ,"max_score_is:",max(score) ) # 打印score中的最大值
all_subject_score = [80, 92, 85, 87, 79, 82, 72]
student_info("小明","男","语文",*all_subject_score) # 传入列表,元组类型的参数时需在参数前添加(星号 *)
实例输出:
name: 小明 sex: 男
subject: 语文 max_score_is: 92
分析:在传入不定长参数时,如果是列表、元组类型的参数,需要在调用中的实参前使用星号(*)声明,这时数据才会被程序拆分出来,否者程序会认为列表、元组为一个参数。
如果想测试的同学,可以将调用函数中实参前的星号(*)去掉,然后再执行,此时程序会输出不一样的结果。
【** 号不定长参数】
双星号 **
不定长参数主要是用来接收字典(dic)类型的数据,多余的参数将被存入一个 字典(dis) 中。实例如下:
实例1:
#! /usr/bin/python3
# -*- coding : utf-8 -*-
def my_function(**aa):
print(type(aa)) # 查看当前 aa 的数据类型
print(aa) # 打印 aa 的数据
my_function(a=1, b=2, c=3)
实例输出:
{'a': 1, 'b': 2, 'c': 3}
分析:可见多余的参数被接收到新的字典当中,其中以形参名作为键(key)值,以实参作为数据(value)。
实例2:
#! /usr/bin/python3
# -*- coding : utf-8 -*-
params = {'name':'justin', 'number':'123-4567', 'balance':1000}
def account(name,number,balance): # 定义 ** 不定长参数
print( {'name_is':name, 'number_is':number, 'balance_is':balance} ) # 通过键获取对应的值
# 调用函数
account(**params)
实例输出:
{'name_is': 'justin', 'number_is': '123-4567', 'balance_is': 1000}
分析:定义**不定长参数时,在函数调用中,函数会根据‘键名’读入相应的‘键值’,即函数的形参将由字典的‘键值’所代替。
注意:在函数内部调用形参的值时,务必在形参的前面加上 :
冒号,否则编译器报错。
return 语句
return 语句主要用于把函数中指定的参数带回到主程序中,当缺省 return 返回表达式时,程序默认返回 None 。
在执行中,当程序执行 return 语句时,程序直接携带参数返回上级程序中(即退出当前函数体)。
注意:同一条件下只允许出现一个return 语句。
基本格式:
return a[,b,c...n]
实例如下:
实例1:
#! /usr/bin/python3
# -*- coding : utf-8 -*-
def custom_sum( a, b ):
return( a + b ) # 返回 a + b 的值
# 调用函数并显示计算结果
print( custom_sum(1000, 24) )
输出结果:
1024
分析:当调用函数时,程序执行函数中的语句,执行到return语句时,return语句将携带 a + b 的运算结果返回到主程序中。
yield 语句
yield 语句同样可以携带参数返回a,但它不会立刻中断当前函数。
实例功能:
模仿 Python 内置函数 range() 函数的功能,代码如下:
#! /usr/bin/python3
# -*- coding : utf-8 -*-
def xrange( n ): # 自定义一个函数
x = 0
while x != n:
yield x # 返回 x 的值
x += 1
for n in xrange(5): # 调用函数
print (n)
实例输出:
0
1
2
3
4
分析:通过分析可以知道程序执行到 yield语句时,并没有退出当前函数,而是继续往下执行,直到最后才返回当时所记录到的值。
lambda 表达式
lanbda 可以理解为是一个小函数, 其函数主体是一个表达式, 而不是代码块。
语法格式:
lambda arg1 [,arg2,.....argn] : expression
参数声明:
- arg1: 定义的变量( 变量间用 , 号间隔)
- expression : 函数体(一般为表达式)
- 返回值: 参数自动返回,无需return语句
实例如下:
#! /usr/bin/python3
# -*- coding : utf-8 -*-
# 定义 lambda 函数
custom_sum = lambda num_1, num_2: num_1 + num_2;
# 调用sum函数
print(custom_sum(1000, 24))
实例输出:
1024
可见 lanbda 表达式会自定返回其值,而无需额外添加 return 语句。
变量作用域
变量的作用域将变量划分为:全局变量 和 局部变量 两种。
- 全局变量:定义在函数以外的变量称为全局变量,该变量可以在程序的任何地方进行调用。
- 局部变量:定义在函数内部的变量称为局部变量,该变量只允许程序在函数内部进行调用。
实例演示:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
total = 0; # 这是一个全局变量
def custom_sum(num_1, num_2):
total = num_1 + num_2; # total在这里是局部变量.
print("函数内-局部变量 : ", total)
# 调用sum函数
custom_sum(1000, 24);
print("函数外-全局变量 : ", total)
实例输出:
函数内-局部变量 : 1024
函数外-全局变量 : 0
以上是简单的 全局变量 和 局部变量 的使用演示,当局部变量需要扩展为全局变量时,可以使用 global 关键字声明,如:global nun1,但一般不建议这样使用。
【其它说明】
1、变量查找规则: 从内到外
2、Python 中全局变量以模块文件为界
3、使用 locals() 函数查看所有局部变量的名字和值
完整学习教程请访问:Python3 入门教程——目录索引