4.Python函数使用

1、函数定义和调用

1.1、定义函数的语法格式

def 函数名称(参数):
  函数体代码
return 返回值
#定义函数
def user_info():
  print("姓名:张三")
  print("性别:男")
  print("年龄:18")
#函数调用
user_info()

2、函数参数

2.1、缺省参数

函数定义时,设置带有默认值的参数,调用时,缺省参数可以不传入,没传使用默认值,传了实参就使用实参

def sum(y,x=10):
  rs=x+y
  print("{}+{}={}".format(x,y,rs))

# 只传入一个参数y的值
sum(10)
# 传入缺省参数的实参20
sum(10,20)

2.2、命名参数

指在调用带有参函数时,通过指定参数名称传入参数的值,并且可以不按照函数定义的参数顺序传入实参

def sum(y,x):
  rs=x+y
  print("{}+{}={}".format(x,y,rs))

# 不按照参数定义的顺序,通过指定参数名称传入,指定参数名称必须与定义的形参名称相同
sum(x=10,y=20)
sum(y=20,x=10)

2.3、带参函数

函数定义时,可以在小括号内设置函数需要的参数,调用时安装顺序和个数传入

def user_info(name,sex,age):
  print("姓名:",name)
  print("性别:",sex)
  print("年龄:",age)

# 调用  
name="张三"
sex="男"
age=18
user_info(name,sex,age)

2.4、不定长参数

  • 带有一个*的不定长参数
# 计算多个数字和
def any_num_sum(*args):
  print("args参数值:",args)
  print("args参数类型:",type(args))
  rs=0
  if len(args)>0:
    for arg in args:
      rs += arg
    print("总和:"rs)
   
# 调用
any_num_sum(10,20)
any_num_sum(10,20,30,40)

注:*args接受的任意参数会封装到元组中

  • 带有两个*的不定长参数
def su(base,**kvargs):
  print("kvargs参数值:"kvargs)
  print("kvargs参数类型:",type(kvargs))
  x=kvargs.get("x")
  y=kvargs.get("y")
  su=base-x-y
  print("计算值:"su)
    
# 调用
su(10,x=4,y=5)

注:**kvargs 接受的参数将封装到字典中

  • 拆包

使用场景:当一个函数设置了不定长参数,想把已存在的元组、列表、字典传入到函数中,并且能够被不定长参数识别,就需要拆包

# 求数字列表中所有元素和
num_list=[1,2,3,4,5]
  
#调用any_num_sum函数
any_num_sum(*num_list)
  
# 求字典中数字计算
su_dict={"x":20,"y":30}
  
#调su函数
su(100,**su_dict)

3、函数返回值

  • 带返回值函数
def x_num(base,**kvargs):
  x1=kvargs.get("x1")
  x2=kvargs.get("x2")
  x_num=base*x1+base*x2
  return x_num

def y_num(yy):
  if yy >0 and yy <= 10:
    return 1
  elif yy <= 0:
    return 2
  elif yy > 10 and yy <100 :
    return 3
  else:
    return 4
  
def su(base):
  su_dict={"x1":10,"x2":20}
  x=x_num(base,**su_dict)
  yy=base+x
  y=y_num(yy)
  su=base+x+y
  print("计算值:su={},x={},y={}".format(su,x,y))
  
#调用
su(60)

4、变量作用域

4.1、局部变量:只能在某个特定的范围内使用

def info1():
  #局部变量
  name="张三"
  age=20
  print("姓名:{},年龄:{}".format(name.age))

def info2():
  #局部变量
  name="李四"
  age=19
  print("姓名:{},年龄:{}".format(name.age))

#调用
info1()
info2()

4.2、全局变量:可以在全局范围内使用

#全局变量
base=100

def sum1(x):
  rs=base+x
  print("{}{}的和{}".format(x,base,rs))

def sum2(y):
  rs=base+y
  print("{}{}的和{}".format(y,base,rs))

#调用
sum1(10)
sum2(20)

5、递归函数

说明:一个函数在其函数体内调用函数自身,这样的函数就是递归函数

# 计算3的阶乘
def factorial(num):
  if num > 1:
    return num*factorial(num-1)
  else:
    return num
  
#调用
factorial(3)

6、匿名函数

6.1、匿名函数语法格式

lambda 参数列表:表达式

6.2、匿名函数作为普通函数的参数

sum=lambda x,y:x+y
#调用
print(sum(10,20))

6.3、将匿名函数赋值给变量,通过变量名调用匿名函数

def x_y_compute(x,y,func):
  print("x={},y={}".format(x,y))
  result=func(x,y)
  print("result={}".format(result))

#调用
x_y_compute(10,20,lambda x,y:x+y)
x_y_compute(10,20,lambda x,y:x*y)

7、闭包

说明:所谓闭包就是指当一个嵌套函数的内部函数引用了外部函数的变量,外部函数的返回值是内部函数的引用,这种函数的表达方式就是闭包

7.1、闭包求和

# 普通函数,求和
def sum(x,y):
  return x+y

sum(10,20)

# 闭包求和

# 1.外部函数
def sum_closure(x):
  #2.内部函数
  def sum_inner(y):
    #3.调用外部函数的变量x
    return x+y
  #4.外部函数返回值是内部函数的引用
  return sum_inner

rs_func=sum_closure(10)
print("rs_func: {}".format(rs_func))
print("rs_func类型: {}".format(type(rs_func)))

#闭包使用
print(rs_func(2))

7.2、闭包计数器

# 闭包计数器
def counter_w(base=0):
  cnt_base=[base]
  def counter(step=1):
    cnt_base[0]+=step
    return cnt_base[0]
  return counter

counter=counter_w()

print("当前计数器值:{}".format(counter()))
print("当前计数器值:{}".format(counter()))
print("当前计数器值:{}".format(counter()))

8、装饰器

8.1、装饰器介绍

就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。

这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌原函数的函数。

语法在被装饰函数前面加 @装饰器名称

8.2、初步使用

  • 有参函数添加装饰器
# 计算程序执行耗时
def time(func):
  def counter(x,y):
    start_time=time.time()
    print("开始时间:",start_time)
    func(x,y)
    end_time=time.time()
    print("结束时间:",end_time)
    print("程序运行耗时时间:",end_time-start_time)
  return counter

@time # 装饰器
def sum(x,y):
  time.sleep(5)
  print("{}+{}={}".format(x,y,x+y))

#调用
sum(1,2)
  • 不定长参数函数添加装饰器
# 计算程序执行耗时
def time(func):
  def counter(*args):
    start_time=time.time()
    print("开始时间:",start_time)
    func(*args)
    end_time=time.time()
    print("结束时间:",end_time)
    print("程序运行耗时时间:",end_time-start_time)
  return counter

@time
def sum(x,y):
  time.sleep(5)
  print("{}+{}={}".format(x,y,x+y))

@time  
def multi(x,y,z):
  time.sleep(5)
  print("{}*{}*{}={}".format(x,y,z,x*y*z))

#调用
sum(10,20)
multi(10,20,30)