🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
关键字参数和不定长参数
关键字参数主要体现在函数的调用上
使用关键字参数的好处是,可以不按照形参的参数传参
比如说,我们定义一个函数
def c1(name,age):
print(f'姓名: {name}, 年龄:{age}')
c1("zhangsan",10)
c1(age=10,name="张三")
这个就是普通函数的定义,我们调用这个函数的时候,需要传入两个参数(因为形参数目是两个)。
我们接下来再来看下一个函数的定义。
def c1(name,age=0,address="北京"):
print(f'姓名:{name},年龄:{age}.地址:{address}')
c1("张三",10)
在这个函数的定义当中,我们在形参中,对age和address进行了赋值,这样做的好处是,即使我们传入的参数小于三个,这个函数仍然可以成立。
并且,我们还可以使用关键字进行传参。
c1(name="张三",age="5")
c1(age=5,name="张三")
c1("李四",address='上海')
你看,这样是不是提高了代码的可读性。
系统函数中的关键字参数
初次之外,其中我们平常使用的系统函数中,都是有关键字参数的。
比如说:print
print(45,6,77,end='-------',sep='*')
那个end和sep就是系统函数中的关键字参数。
* 和**
这两个的区别主要在于
* 被当做元组处理
** 被当做字典处理
比如说,我们看下面的这两个代码。
def d1(*num):
print(num)
print(type(num))
d1()
d1(45)
def d2(**num):
print(num)
print(type(num))
d2()
这个时候传参的时候,就必须写成变量等于什么的形式,例如:
d2(x=2,y=4,z=5) # 类似于字典的创建方式3
这种是类似于字典的创建方式。
在同一个函数当中,同种符号只能出现一次,但是*和**可以同时出现。
def d3(*num1,**num2):
print(num1,num2)
d3(45,5,6,7,8,9,5)
d3(a=5)
d3(4,7,8,6,5,ac=5)
这个代码执行下来的结果如下图所示:
函数的本质,其实就是一个变量,函数名其实就是一个变量名。
name = "zhangsan" # 变量
def func1(): # 函数
print("111111111")
print(type(name)) #<class 'str'>
print(type(func1)) #<class 'function'>
func1()
你看,是不是其实蛮相似的。
如果这个时候我们重新给func1进行复制,这样子可以吗?
func1=10
答案当然是可以的,但是这个时候func1的类型就发生了改变。
print(type(func1)) # <class 'int'>
我们前面说函数和变量是很类似的,与给函数赋值和给变量赋值,结果也是极其相似的,我们来看一下给变量的赋值。
name=[243,6,78,8]
print(type(name)) # <class 'list'>
我们可以看到的是,他的类型变成了列表。
而func1() 这个时候是不能进行调用的,是运行不起来的,因为这个时候它的类型发生了改变。
原来表示函数的含义消失了。
所以这个时候也给我们提了一个醒,那就是自定义标识符的时候,不要使用系统的函数名,否则会导致系统的函数失效。
print=32
print(print)
sum=327
print(sum(3,527))
这两个系统的函数都失去了原来的作用。并变成了自己赋给的int类型。
A函数可以作为B函数的参数或者返回值使用,只需要传递或返回函数名就可以了。
使用场景:闭包、高阶函数、装饰器等
大家可以先来看下面的这个场景。
def func1():
num1=78
def func2():
num2=13
total = num1+num2
print(total)
func2()
这个代码是会报错的,因为func1中的变量在func2中是无法直接使用的,因为两个的作用域并不相同。
那么应该怎么解决这个办法呢?
方法一:返回值
def func1():
num1=78
return num1
def func2():
num2=13
total = func1()+num2
print('和: ',total)
方法二:函数的嵌套定义
def func1():
print('11111111---------start')
num1=78
def func2():
print('2222222--------start')
num2=13
total = num1+num2
print('和: ',total)
print('222222----------end')
print('11111111---------end')
func1()
这个其实我们需要着重讲一下。
首先,在上面的这个嵌套定义的代码中,执行结果是这样的。
print(num1) #num1只能在func1内部使用
当我们执行这个代码的时候,是会报错的,这是因为num1只能在func1内部使用
func2() #这里不能调用,这个func2只能在func1内部使用
这个代码执行也会报错,也是因为func2只能在func1的内部调用。那我们应该如何调用嵌套定义的函数呢?
方法一、直接在func1中调用
def func1():
print('11111111---------start')
num1=78
def func2():
print('2222222--------start')
num2=13
total = num1+num2
print('和: ',total)
print('222222----------end')
#调用内部函数func2()
func2()
print('11111111---------end')
#调用外部函数func1()
func1()
def func1():
print('11111111---------start')
num1=78
def func2():
print('2222222--------start')
num2=13
total = num1+num2
print('和: ',total)
print('222222----------end')
#调用内部函数func2()
print('11111111---------end')
func2()
#调用外部函数func1()
func1()
方法二、将func2设置为func1的返回值,这种方式以后是常用的,主要应用在闭包或者装饰器当中。
def func1():
print('11111111---------start')
num1=78
def func2():
print('2222222--------start')
num2=13
total = num1+num2
print('和: ',total)
print('222222----------end')
#调用内部函数func2()
print('11111111---------end')
# A函数作为B函数的返回值使用,只需要使用函数名可以
return func2 # func2表示函数本身,func2()表示调用函数
f = func1() # f中存储的是func1的返回值
# print(f) # f中存储的是func2函数
f() # 相当于调用fcun2()函数
闭包的使用
闭包的前提是函数的嵌套定义,在内部函数当中使用了外部函数的变量。
情况一
返回值
def func1():
num1=78
def func2():
num2=13
total = num1+num2
print('和: ',total)
return func2
f=func1()
f()
情况二
def func1(a,b,c):
num1=78
def func2():
num2=13
total = num1+num2
print('和: ',total,a,b,c)
return func2
f=func1(45,7,8)
f()
情况三
def func1(a,b,c):
num1=78
def func2(x,y):
num2=13
total = num1+num2
print('和: ',total,a,b,c,x,y)
return 'hello'
return func2
f = func1(45,7,8)
x = f(4,7)
print(x)
f表示的是func2
无论是函数的嵌套定义还是闭包,本质还是一个函数,所以默认参数,关键字参数和不定长参数都可以正常使用
返回值也可以正常使用
所在在调用内外函数的时候,一定要注意参数的传参的问题