今日内容概要
- 函数的定义与调用
- 函数的分类
- 函数的返回值
- 函数的参数
- 名称空间与作用域
今日内容详细
一、函数的定义与调用
- 函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是对这段代码的引用
- 函数的使用分为定义阶段与调用阶段,定义函数时只检测语法,不执行函数体代码,函数名加括号即函数调用,只有调用函数时才会执行函数体代码
#######################################
# 1.函数一定要遵循先定义后调用的原则
大白话:定义函数的代码一定要比调用函数的代码先执行
# 2.函数在定义阶段只检测语法不执行代码
# 3.函数体代码只有在调用函数的时候才会执行
调用函数的方式>>>:函数名加括号 # 如果有参数则传递参数
# 4.函数名其实相当于是变量名指向的是内存中函数体代码所在的位置
#######################################
func() # 报错 name 'func' is not defined
# 定义函数
def func():
print('hello world')
# 调用函数
# func() 就是去内存中找到函数体代码并执行
二、函数的分类
1、内置函数
- python解释器提前定义好可以直接调用的函数
eg:len、open… # 如何查看代码的内部源码ctrl+鼠标左键
2、自定义函数
- 程序员自己编写的函数
- 自定义函数又分为:
2.1 无参函数
2.2 有参函数
2.3 空函数
- 参数是函数的调用者向函数体传值的媒介,若函数体代码逻辑依赖外部传来的参数时则需要定义为参函数,
2.1 无参函数 :在函数定义阶段括号内没有参数
调用无参函数:括号内也不需要写参数
index()
2.2 有参函数 :在函数定义阶段括号内有参数>>>:类似于变量名
def index(a):
print('嘿嘿嘿 妹纸有事冲我来',a)
调用有参函数:在函数调用阶段括号内也必须传参数>>>:类似于变量值
index(123)
2.3 空函数 :在定义阶段函数体代码是用pass或者…占位
def index():
pass
"""
空函数感觉一点用都没有啊 但是非常有用
前期能够通过空函数快速的罗列出程序中大致的功能
让程序整体框架清晰 空函数大量的使用在项目前期的功能框架搭建
eg:编写一套程序
功能也可以看成是函数 函数也可以看成是功能
"""
def fight():
pass
def run():
pass
def study():
pass
def communication():
pass
三、函数的返回值
- 定义:函数的返回值其实就是在调用函数之后返回的结果
eg:
s = 'hello world'
res = len(s) # 将len函数的返回值赋值给变量res
print(res)
- 如何获取函数的返回值
变量名 = 函数调用 - 如何操作返回值
- 当函数体代码没有return关键字的时候 返回值是None
def index():
print('春困秋乏夏打盹儿')
res = index()
print(res) # None
- 当函数体代码写了return但是没有跟任何值得时候 返回值也是None
def index():
print('春困秋乏夏打盹儿')
return
res = index()
print(res) # None
- 当函数体代码写了return并且跟了数据 那么写什么就返回什么
如果写的是值那么直接返回值(任意数据类型)
如果写的是变量名那么返回变量名指向的值
def index():
print('春困秋乏夏打盹儿')
name = 'jason'
return name
res = index()
print(res) # jason
- return后面还可以跟多个值 逗号隔开 会自动组织成元组后返回出去
def index():
print('春困秋乏夏打盹儿')
return 111,'jason',222
res = index()
print(res) # (111,'jason',222)
- 函数体代码遇到return会立刻结束函数运行,函数体代码里面写return相当于循环体代码里面写break
- return是一个函数结束的标志,函数内可以有多个return,但只执行一次函数就结束了,并把return后定义的值作为本次调用的结果返回。
四、函数的参数(重要)
- 函数的参数分为形式参数和实际参数,简称形参和实参:
- 形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。
实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合:
"""
##############################################
1.函数的参数可以分为两大类
1.函数在定义阶段括号内写的参数
我们称之为'形式参数' 简称为>>>:形参
2.函数在调用阶段括号内写的参数
我们称之为'实际参数' 简称为>>>:实参
2.形参与实参的关系
形参类似于是变量名、实参类似于是变量的值
在调用函数的时候传入实参 会与形参临时绑定
函数运行结束之后自动解除绑定
###############################################
"""
def index(a,b): # a和b就是index函数的形参
print(a,b)
index(1,2) # 1和2就是index函数的实参
"""
1会临时绑定给形参a 2会临时绑定给形参b
函数体代码运行期间 可以通过形参直接使用到实参
函数体代码运行完毕之后 解除绑定
形参ab处于没有绑定值得状态 等待下一次函数调用传入实参进行绑定
"""
五、位置参数
位置即顺序,位置参数指的是按顺序定义的参数
- 位置形参
在函数定义阶段括号内从左往右依次填写的变量名
def index(name,pwd): # name和pwd就是位置形参
pass
- 位置实参
在函数调用阶段括号内从左往右依次传入的真实数据
index('jason',123) # jason和123就是位置实参
- 位置参数的特征
- 置形参与位置实参在绑定关系的时候就是按照从左往右的顺序依次绑定
- 位置形参与位置实参的个数要一致(一 一对应) 多一个不行少一个也不行
def index(a, b):
print(a, b) # 外界传入什么实参这里就打印什么
index(1,2)
index('jason',123)
index() # 调用的时候不传实参不可以
index(111) # 传少了也不行
index(111,222,333) # 传多了也不行
六、关键字参数
出现在实参中
指名道姓的给形参传值 不需要遵循位置
- 在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
- 需要注意在调用函数时,实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
def index(a, b):
print(a, b)
index(b=111, a=222) # 指名道姓的说形参a接收数据222 b接收数据111
index(b=333,222) # 报错 关键字参数必须放在位置参数的后面
index(222,a=111) # 报错 形参只能指向一个实参
index(222,b=111) # 可以 相当于位置参数
"""
实参222会按照位置绑定给形参a 然后又通过关键字参数给形参a重复绑值
这种情况是不被允许的!!!
"""
七、默认参数
出现在形参中
在函数定义阶段就已经给一些形参赋值了
后续如果不传值则使用默认的
后续如果传值则使用传入的
默认参数的出现也打破了形参与实参之间个数一致的情况
需要注意:
1. 默认参数必须定义在位置参数的后面
2. 默认参数的值仅在函数定义阶段被赋值一次
- 在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。例如编写一个注册学生信息的函数,如果大多数学生的性别都为男,那完全可以将形参sex定义成默认参数
def register(name, age, gender='猛男'):
"""
函数的形参在命名的时候也应该见名知意
"""
print("""
学员姓名:%s
学员年龄:%s
学员性别:%s
""" % (name, age, gender))
register('jason', 18) # 不传就使用默认的
register('kevin', 28)
register('jerry',22,'美女') # 传了就使用自己的
八、可变长参数(*与**的用法)
- 参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
- 可变长参数
1).单星号*在形参中
可以接收多余的位置参数 并组织成元组的形式赋值给号后面的变量名
2).双星号** 在形参中
用于接收多余的关键字参数 并且组织成字典的形式赋值给**后面的变量名
九、可变长形参
def func(*a,**k):
print(a,k)
func() # () {}
func(1,2,3,4,name='jason',age=18) # (1, 2, 3, 4) {'name': 'jason', 'age': 18}
# 以后在定义函数的时候 如果不确定这个函数将来需要多个实参 那么可以采用上述的方法
"""*和**在形参中的使用 后面的变量名并不是关键 但是针对这两个特殊符号后面的变量名 有推荐的写法"""
def index(*args, **kwargs):
pass
*和**不单单可以在形参中使用 还可以在实参中使用
def index(*args, **kwargs):
print(args, kwargs)
"""
*号在实参中
可以将列表或者元组打散成位置参数一一传入
def index(*[11,22,33]) 等价于 index(11,22,33)
def index(*(11,22,33)) 等价于 index(11,22,33)
如果真的理解不了 可以看成是*号会将列表和元组的括号去除 暴露出里面一个个元素
"""
# index(*['jason', 'kevin', 'tony', 'oscar', 'jerry']) # ('jason', 'kevin', 'tony', 'oscar', 'jerry') {}
# index(*('jason', 'kevin', 'tony', 'oscar', 'jerry')) # ('jason', 'kevin', 'tony', 'oscar', 'jerry') {}
# index(['jason', 'kevin', 'tony', 'oscar', 'jerry']) # (['jason', 'kevin', 'tony', 'oscar', 'jerry'],) {}
# print(*[1,2,3]) # print(1,2,3)
"""
**号在实参中
可以将字典打散成关键字参数一一传入
def index(**{'name':'jason'}) 等价于 index(name='jason')
"""
index(**{'name':'jason','age':18,'pwd':123}) # () {'name': 'jason', 'age': 18, 'pwd': 123}
index({'name':'jason','age':18,'pwd':123}) # ({'name': 'jason', 'age': 18, 'pwd': 123},) {}