函数的动态参数
-
1.函数的动态参数
位置参数,默认参数
动态参数的作用 *args
1.能够接受不固定长度参数
2.位置参数过多时可以使用动态参数
-
动态参数的用法:
def func(*c): #形参位置上的 * 是聚会 print(*c) #函数体中的 * 就是打散 #func(1,2,3,4,5,6,7,8,9,0)
-
def eat(a,b,*args): #位置参数,动态位置参数
print(a,b,args) #结果:面条 包子 ('饺子', '馅饼', '馒头')
print(a,b,*args) #带上*是打散 面条 包子 饺子 馅饼 馒头
eat("面条","包子","饺子","馅饼",”馒头“)
按照位置面条和包子一一对应 a,b 剩余的全给了 args 动态位置参数
错误的示例
def eat(*args,a,b): # 位置参数,动态位置参数# print(a,b,args) ## eat("面条","米饭","馒头","包子","煎饼") 就会报错,因为args会全部接受实参,没有实参给a,b
def func (a,b,*args,c=2,**kwargs): #位置参数,动态参数,默认参数 print(a,b,c,args,c,kwargs) #1 2 100 (3, 4, 5, 6, 7, 8, 565) 100 {'w': 3, 'd': 3} func(1,2,3,4,5,6,7,8,565,c=100,w=3,d=3)
-
def func(a,b,*args,m=8,**kwargs,) #位置参数,动态参数,默认参数,动态关键字参数
位置参数,动态参数,默认参数,动态关键字参数
*args
程序之间约定(可以更换但是不建议更换)
**kwargs
程序员之间约定俗称(可以更换但是不建议更换)
*args
获取的是一个元组
**kwargs
获取的是一个字典
*args
只接受多余的位置参数 一定要放到参数最后
**kwargs
只接受多余的关键字参数 一定要放到参数最后
函数参数优先级 位置参数>动态位置参数>默认参数>动态关键字参数
lst = [1,2,3,4,5,7]
def func(*args):
print(*args) # 打散 输出结果 1 2 3 4 5 7
func(*lst) # 函数调用 必须加* 在实参的位置上用*将lst(可迭代对象)按照顺序打散
dic = {"key":1,"key2":2}
def func(**kwargs):
print(*kwargs) # key key2 获取的是键 一个*只获取键
print(kwargs) #{'key': 1, 'key2': 2}
# print(**kwargs) #报错
func(**dic) #打散
函数的注释(给别人看的)
def add(a,b):
"""
填写你作什么运算
:param a: a 是什么数据类型
param b: b 是什么数据类型
return:
"""
例子:
# def add(a,b):
# """
# 数字的加法运算
# :param a: int
# :param b: int
# :return: int
# """
# return a + b# print(add(1,2))
# print(add.__doc__) 查看函数注释 引号之间的内容都能print出来
print(a.__name__) 查看函数名字 add
# print(add())
# print(add.__doc__) # 查看函数的注释
# print(a.__name__) # 查看函数的名字
函数的名称空间
名称空间:
-
内置空间: 存放python自带的一些函数
-
全局空间:当前py文件顶格编写的代码开辟的空间
-
局部空间:函数开辟的空间
#程序加载顺序:内置空间>全局空间>局部空间
#程序取值顺序:局部空间>全局空间>内置空间
作用域
1.全局作用域:内置+全局 globals() #查看全局作用域
2.局部作用域:局部 locals () #查看当前作用域
a = 10
def func():
b = 5
print(locals()) #{'b': 5} 说明b只能作用在函数体内,当作局部变量,全局不能使用 查看的是当前作用域中方法和属性 有b的属性(当前是局部作用域)
print(locals()) #结果中有“a”:10 没有b 查看的是当前作用域中方法和属性 有a的属性 说明全局作用域无法使用局部的变量
函数的第一类对象及使用
函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量
1.函数名可以当作值,赋值给一个变量
示例
def func():
print(1)
a = func
print(func) #函数的内存地址
print(a) #函数的内存地址
a( )
执行函数, 因为func
赋值给了a
, a()
跟func()
一样,调用函数func()
2.函数名可以当作另一个函数的参数来使用
示例
def func():
print(1)
def foo(a): #a = func
print(a) #func这个函数的内存地址
foo(func)
3.函数名可以当作另一个函数的返回值
示例
def func():
print(1111)
return 1
def foo(a):# a= func函数的内存地址
return a #return func函数的内存地址
cc = foo(func)
print(cc) func函数的内存地址 <function func at 0x0000020BA0A5CD90>
cc() 1111 执行func函数了
4.函数名可以当作元素存储在容器中
示例
def func():
print(1)
def foo():
print(2)
def f():
print(3)
lst = [func,foo,f]
for i in lst:
i() #调用i 这个意思是将func foo f 三个函数整体调用
若只是print(i) 得到的是三个函数的内存地址
示例:
def login():
print("登录")
def register():
print("注册")
def shopping():
print("逛")
def add_shopping_car():
print("加")
def buy_goods():
print("买")
msg ="""1.注册2.登录3.逛4.加5.买请输入您要选择的序号:"""
func_dic ={"1":register,"2":login,"3":shopping,"4":add_shopping_car,"5":buy_goods}
while True:
choose = input(msg)
if choose in func_dic:
func_dic[choose]()
else:
print("滚")
函数的嵌套
- 只要遇见了()就是函数的调用. 如果没有()就不是函数的调用
- 函数的执行顺序
def func():
print(1)
print("我太难了")
print(2)
def foo(b):
print(3)
ss = b()
print(ss)
print(4)
def f(a,b):
a(b)
f(foo,func) 输出 3 1 我太难了 2 none 4
def func(a,b):
def foo(b,a):
print(b,a)
return foo(a,b) #先执行函数调用
a = func(4,7)
print(a) 输出结果是4,7 NONE a = func 赋值的是地址,输出地址
a = func() 输出的是return 默认是none
def func():
print(1)
def foo(a,b):
def f(a,b):
print(a,b)
func()
f(b,a)
foo(1,2) 输出2 1 1
def func(a,b):
a = a + b
b = a + 10
def foo(a,d):
def f(e,f):
print(f,e)
return "我太难了"
return f(d,a) # return "我太难了"
return foo(b,a) # return "我太难了
print(func(2,3)) # print "我太难了"
**global **
# global只修改全局空间中的变量
# 在局部空间中可以使用全局中的变量,但是不能修改,如果要强制修改需要添加global
# 当变量在全局存在时global就是申明我要修改全局的变量
# 当变量在全局中不存在时global就是申明要在全局创建一个变量
def func():
global a #申明修改的全局变量,如果外层全局没有此变量就是创建
a = 10
b = a + 12
print(b)
func() #22
print(a) #10 外层print(a) 得到了10,说明global创建了全局变量
nonlocal
# nonlocal: 只修改局部空间中的变量,最外层的一个函数
# 只修改离nonlocal最近的一层,如果这一层没有就往上一层查找,只能在局部
# nonlocal 不能进行创建