5.1 三元运算

v = 前面 if  条件判断 else 后面
#等同于
if 条件判断 :
前面
if 条件判断:
后面

5.2 函数

本质 : 将N行代码拿到并另起名字,以后使用的时候方便调用。

应用场景 :多行代码重复,

函数最好控制在满屏内,多余代码可以使用函数分割。

5.2.1 函数基本结构

#def函数定义   #定义的函数名称    #()里面可以填型参,形参就类似于变量
def            get_file        ():  #冒号结尾
        #函数内容
    
get_file()   #函数的调用

5.2.2 函数的参数

函数的参数暂分为形式参数(形参),和实际参数(实参)

形参:类似于之前我们学到的变量,是一个虚拟的元素,本身并没有实际数值

实参:实参里面的数对应形参,就像给变量赋值一样。

def static_num(num):  #这里的num就是形参
    v = [11,22,33,44]
    print(v[num])
    
static_num(0)      #static_num 就是实参,函数调用后实参把值赋给形参参与运算
static_num(1)
static_num(2)

5.2.3 返回值

def func():
    return 666  #返回值为666,默认为 return NONE
c4 = fun('afafaafafa')

总结

# 情况1
def f1():
    pass 
f1()

# 情况2
def f2(a1):
    pass 
f2(123)

# 情况3
def f3():
    return 1 
v1 = f3()

# 情况4
def f4(a1,a2):
    # ... 
    return 999
v2 = f4(1,7)

5.2.4参数

注意:对于函数的默认值慎用可变类型

# 如果要想给value设置默认是空列表

# 不推荐(坑)
def func(data,value=[]): 
    pass 

# 推荐
def func(data,value=None):
    if not value:
        value = []

 

1.基本参数认识

  • 任意个数
  • 任意类型
def  fun(a1,a2,a3):
    pass
fun(1,2,3)

2.位置传参

函数调用时根据位置传入函数里,一一对应,否则会出错

3.关键字传参

函数调用时指名形参,位置可以调换,但关键字参数必须要在位置参数之后。

def func(a1, a2):
    print(a1, a2)

func(a2=99,a1=2)

# 关键字传参数和位置传参可以混合使用(位置传入的参数 > 关键字参数在后 = 总参数个数)
def func1(a1, a2, a3):
    print(a1, a2, a3)

# func(1, 2, a3=9)
# func(1, a2=2, a3=9)
# func(a1=1, a2=2, a3=9)
# func(a1=1, 2,3) # 错误

3.1传参例子:

def func(a1,a2,a3=9,a4=10):
    print(a1,a2,a3,a4)

func(11,22)
func(11,22,10)
func(11,22,10,100)
func(11,22,10,a4=100)
func(11,22,a3=10,a4=100)
func(11,a2=22,a3=10,a4=100)
func(a1=11,a2=22,a3=10,a4=100)

 

4.全能传参(*args和**kwargs)

*args

  • 可以接收任何个位数的位置传参,并将其转换为元组
#调用函数无*
def func(a1,a2,*args):
    pass
func(1,2,3,4,5,6,7,8,9,0)#  如果不加* 直接传入下一个序列函数会将序列当成一个元素加到一个元组中

# * 的作用相当于拆包,将序列中的元组拆出来一个放入元组中
  • 调用函数有*
def func(a1,a2,*args):
    pass
func(1,2*[1,2,3,4,5,6,7,8,9,0])#
  • 注:只能使用位置传参
def func(*args):
    print(args)

# func(1)
# func(1,2)
func(1,2) # args=(1, 2)
func((11,22,33,44,55)) # args=((11,22,33,44,55),)
func(*(11,22,33,44,55)) # args=(11,22,33,44,55)

**kwargs

  • 可以接收任何个位数的关键字传参,并将其转换为字典

调用时无*

def fun(**kwargs):
    print(kwargs)
fun(a1='你很好',a2='但我们不合适') #接受键值对放入一个字典当中

调用时有*

def fun(**kwargs):
    print(kwargs)
fun(**{'k1':'v1','k2':'v2','k3','v3'})
#{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

只能使用关键字传参

无敌组合:args和kwargs 无敌 + 无敌 => 真无敌

def func(*args,**kwargs):
    print(args,kwargs)

# func(1,2,3,4,5,k1=2,k5=9,k19=999)
func(*[1,2,3],k1=2,k5=9,k19=999)  #(1, 2, 3) {'k1': 2, 'k5': 9, 'k19': 999}
func(*[1,2,3],**{'k1':1,'k2':3})   #(1, 2, 3) {'k1': 1, 'k2': 3}
func(111,222,*[1,2,3],k11='alex',**{'k1':1,'k2':3})   #func(111,222,*[1,2,3],k11='alex',**{'k1':1,'k2':3})

参数重点

def fun1(a1,a2):
    pass
def fun2(a1,a2=999)
pass
def fun3(*args,**kwargs)
pass

注意:位置参数>关键字参数

5.2.5函数作用域以及函数嵌套

全局作用域: 整个py文件

局部作用域:函数体内

总结,一个函数就是一个作用域,如果自己作用域中没有就去父级作用域找,还没有就再往上,直到全局变量里,如果全局变量李还没有就会报错。

练习题:参考练习题5.2.5

  • 子作用域中只能 找到父级中的值 ,默认无法重新为父级的变量进行赋值。(global/nonlocal可以强制做)
     
  • global和nonlocal练习题:参考练习题5.2.5.1

总结:

  • 调用函数时,传参 --> 位置传参>关键字传参
  • 定义函数时:
    def fun(a.b):
    def fun (a,b=999) #如果关键字参数为可变类型,有坑
    def fun(*args,**kwargs) 万能

 

  • 作用域:
  • 函数为自己的作用域
  • 函数寻找参数时,现在自己作用域里面找,没有的话返回父级找,没有再返回父级,直到到全局变量里 #全局读/修改可变
  • 重新赋值:
  • global 寻找全局变量
  • nonlocal #寻找父级变量

补充:

全局变量以后全部大写以方便识别