函数基础知识2
-
函数的定义与调用
-
函数的分类
-
函数的返回值
-
函数的参数
-
名称空间与作用域
今日内容详细
一、函数的定义与调用
# 1.函数一定要遵循先定义后调用的原则:定义函数的代码一定要比调用函数的代码先执行
# 2.函数在定义阶段只检测语法不执行代码
# 3.函数体代码只有在调用函数的时候才会执行
调用函数的方式:函数名加括号 如果有参数需要写入传递参数
# 4.函数名其实相当于变量名指向的是内存中函数体代码所在的位置
注意:如果一个函数没有定义阶段,那么将无法被调用 eg:func() 出现的结果是:系统会报错 name 'func' is not defined
函数基本格式:定义函数+调用函数
定义函数:
def func():
print('hello world')
调用函数:
func() 实质是去内存中找到函数体代码并执行
二、函数的分类
1.内置函数
是指在Python解释器中提前定义好后可以直接调用使用的函数
比如:len、open、print.....
查看代码的内部源码Ctrl +鼠标左键点击即可
2.自定义函数
是指程序员自己编写的函数,其中又可以分为三类:无参函数、有参函数、空函数
无参函数:在函数“定义阶段”括号内没有参数 eg:
def index():
print('hello world')
在调用无参函数:括号内也不需要写参数
# index()
有参函数:是在函数“定义阶段”括号内有参数 '可以类似于变量名'
def index(a):
print('hello world')
在调用有参函数时:调用阶段括号内也必须写参数 '可以类似于变量中的变量值'
# index(a)
空函数:是指在“定义阶段” 函数体代码是用pass或者...先占位 eg:
def index():
pass
空函数从定义上看觉得没有什么作用,但是在我们实际上是非常有用:
前期利用空函数来列大纲,快速罗列出程序中我们需要写的功能
让程序整体框架结构清晰 搭建好整个框架
以后在编程书写时:功能可以看成是函数 函数也可以看成是功能
三、函数的返回值
# 函数的返回值其实就是在调用函数后计算机返回给你的结果
先给你举个例子:
s ='hello world'
res = len(s) # 意思是将len函数的返回值绑定一个名字赋值给了res这个变量名
print(res) # 然后我们就可以通过res就可以找到len函数的返回值
# 如何获取函数的返回值 (书写格式)
变量名 = 函数调用
res = index()
print(res)
# 对于如何控制返回值
1.当函数体代码没有return关键字的时候 返回值是None
def index():
print('好好学习 天天向上')
res =index()
print(res) # 会出现报错
2.当函数体代码写了return但是没有跟任何值的时候 返回值也是None
def index():
print('好好学习')
return
res = index()
print(res) # None
3.当函数体代码写了return并且跟了数据 那么写了什么就会返回什么
如果写的是值那么直接返回值(任意数据类型)
如果写的是变量名那么就是返回变量名指向的变量值
def index():
print('好好学习')
name ='jason'
return name
res = index()
print(res) # jason
4.return后面还可以跟多个值 中间用“逗号”隔开 返回值会自动组织成“元组”出去
def index():
print('好好学习')
name ='jason',111,222
return name
res = index() # ('jason', 111, 222)
5.函数体代码遇到return会立即马上结束函数的运行
函数替代码里面写了return类似于在循环结构中写了break 遇到了就马上回立刻结束函数和循环的执行
四、函数的参数
# 1.函数的参数可以分为两大类:形参和实参
形参:是指函数在“定义阶段”括号内写的参数,也叫形式参数,简称为:行参
实参:是指函数在“调用阶段”括号内写的参数,也叫为实际参数,简称为:实参
# 2.形参与实参的关系
两者从定义上来区分就是参数所在阶段的不同而不同
形参类似于变量中的变量名 实参类似于变量中的变量值
在调用函数的时候会传入实参 先与形参临时绑定 后函数运行结束后自动解除绑定,然后下一个实参继续反复的一个动态过程 例如:
def index(a,b): # a与b就是index函数的形参
print(a,b)
# index(1,2) # 1和2就是index的实参
实参数字1会临时绑定给形参变量a,数字2会临时绑定给形参变量b(如果一般情况默认是从左到右 一一对应)
函数体代码运行完毕后 两者的绑定会自动解除
此时的形参a、b仍处于没有绑定的状态 等待下一组函数调用再传入实参进行绑定
五、位置参数
位置形参:是指在“定义阶段”括号内从左往右依次填写的变量名
def index(name,pwd): # 其中name和pwd就是位置形参
pass
位置实参:是指在函数“调用阶段”括号内从左往右依次传入的真实数据(变量值)
# index('jason',123) # jason和123就是位置实参
位置参数的特征
1.位置形参与位置实参在绑定关系的时候就是按照从左往右的顺序依次绑定
2.位置形参与位置实参的个数两者要一致 如果不一致(多或少)系统会报错
def index(a,b):
print(a,b) # 外界传入什么实参这里就打印什么
# index(1,2) # 1 2
# index('jason',123) # jason 123
# index() # index() missing 系统会报错 不传实参不行
# index(111) # 实参传少了也不行 index() missing
index(111,222,333) # 传多了也不行 index() takes 2 positional
六、关键字参数
出现在实参中
指名道姓的给形参传值 不需要遵循位置(从左往右 一一对应)
def index(a,b):
print(a,b)
index(b=111,a=222) # 指名道姓的说形参a接收数据222 b接收数据111
index(b=333,222) # 关键字参数必须放在位置参数后面 否则会报错
index(222,a=111) # 会出现a会等于两个值 计算机无法识别报错 形参只能指向一个实参
index(222,b=111) # 可以运行 相当于位置参数
七、默认参数
# 出现在形参中:在函数定义阶段就已经给一些形参赋值了
后续如果不传达实际值则使用默认的数值
后续如果传值则是使用传入的
默认参数的出现也打破了形参与实参之间个数一致的情况
默认参数必须定义在位置参数后面 # 至于顺序问题 后面有口诀
默认参数的实际应用案例
比如:很多软件的注册页面 默认会帮助我们勾选一些选择
def register(name,age,gender ='男生') # 函数的形参在命名的时候也应该做到见名知意(默认参数必须定义在位置参数后面)
print("""
学员姓名:%s
学员年龄:%s
学员性别:%s"""%(name,age,gender))
register('jason',18) # 不传就使用默认的
register('kevin',28)
register('jerry',22,'女生') # 我们传了就会使用自己的
八、可变长参数
# 在实际生活中,我们会遇到这样的需求:需要定义一个函数 无论传多少位置实参都可以正常执行
这就引出了*与**k,先看例题
def func(*a):
print(a)
func() # () 没有实参则打印空
func(1,2) # (1,2) 有实参则会接收(1,2) 然后赋值给*号后面的变量名
func(1,2,3,4,5,6) # (1,2,3,4,5,6) 有什么实参就会接收什么实参,然后赋值给*号后面的变量名
*号在形参中
可以接收多余的位置参数 并组织成“元组”的形式赋值给*号后面的变量名
def index(a,b,*ag):
print(a,b,ag)
index(999) # 系统会报错 因为参数a b的存在 意味着index最少要给两个参数
index(1,2) # 1 2 ()
index(1,2,3,4,5,6,7) # 1 2 (3,4,5,6,7)
index(1,2,3,4,5,6,7,8,9,10) # 1 2 (3,4,5,6,7,8,9,10)
**在形参中:
用于接收多余的关键字参数 并且组织成“字典”的形式赋值给**后面的变量名
例如:
def index(a,b,**k):
print(a,b,k)
index(a=1,b=2) # 1 2 {}
index(a=1,b=2,c=3,name='jason') # 1 2 {c:3,'name':'jason'}
index(1,2,name='jason',age=18,pwd=123) # 1 2 {'name': 'jason', 'age': 18, 'pwd': 123}
如果定义一个函数需要无论传入多少关键字参数都可以正常执行
九、可变长形参
# 如何定义一个无论接收多少个任意类型的参数都可以正常执行的函数
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)
可以看成是*号会将列表和元组的括号去掉暴露出里面一个个元素
**号在实参中
• 可以将字典打散成关键字参数一一传入
def index(**{'name':'jason'}) 等价于index(name='jason')
index(**{'name':'jason','age':18,'pwd':123})
# {'name': 'jason', 'age': 18, 'pwd': 123}
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)
可以看成是*号会将列表和元组的括号去掉暴露出里面一个个元素
**号在实参中
• 可以将字典打散成关键字参数一一传入
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},)