Python基础教程(12)函数与参数

TangLu 未命名 2019-12-12 3498 0

一、什么是函数

函数就是执行特定任务以完成特定功能的一段代码。这一段代码被定义为一个函数后可以重复调用,增强代码复用率。在调用函数的时候接收到的输入信息被称为参数,在结束调用后输出的信息被称为返回值


二、Python函数的定义与调用

· 定义与调用无参数函数

# def 函数名(); 
#   代码块
#   [return 返回值]  #如果没有return的话返回None
  
#定义函数
def  info1():
    print("真的太难了")
    
#调用函数时输入定义好的函数名即可   
info1()  #输出真的太难了


· 定义与调用有参数函数

参数分为形参与实参,在函数定义的时候设置的为形参,在实际调用的时候传递的参数为实参

#def  函数名(参数1,参数2,...);
#    代码块
  
#定义有参数函数示例
def  info2(text):
    print(text)
    
#调用函数时需要传递一个参数给text   
info2('你好')  #输出你好


三、Python函数的参数类型与介绍

1、位置参数

在定义和传递参数时,实参的个数要和形参对应

def calc(num1,num2)        #定义calc函数时定义了2个形参
  result = num1 + num2
  print(result)

calc(10,20)                
calc(num2=5,num1=2)        #也可以通过关键字指定实参的值,不用强行按照形参的顺序来定义,更灵活


2、默认参数

如果代码中有大量参数的最终值可能都是相同的,可以使用默认参数的形式减少代码量。默认参数就是提前为参数设置一个默认值,在调用参数的时候可以不再去为该参数传递任何的数据,如果在实参里又定义了值,那么则覆盖默认参数的值。由于默认参数后面只能是默认参数,所以在定义和调用默认参数时要把默认参数放在后面,不要穿插有形参

def abc(a=300,b=400)
  print(a+b)

abc()   #使用默认参数的值  
abc(b=1000)  #指定一个默认参数进行传值
abc(600,300)  #使用传递的参数覆盖默认参数
abc(500)  #为第一个默认参数传值


def student_info(name,sex,age,school='清华大学'):    #为school参数设置了默认值
student_info('张三','男','7')                        #这里只传递了3个参数,因为school有默认值,可以不写


如果给形参设置的默认值是一个可变类型,比如列表,然后在调用函数时修改了形参的默认值,那么后续再调用该函数时,形参的默认值将会是修改后的值。如果要避免这种情况,可以将形参默认值定义为None

#重复调用该函数时,names参数的默认值会发生变化
def fun1(names=[]):
  names.append('tanglu')
  print(names)
fun1()  #输出[tanglu]
fun1()  #输出[tanglu,tanglu]
fun1()  #输出[tanglu,tanglu,tanglu]

#
def fun2(names = None):
  if names is None:
   names = []
  names.append('tanglu')
  print(names)
fun2()  #输出[tanglu]
fun2()  #输出[tanglu]
fun2()  #输出[tanglu]


3、可变参数(动态参数、不定长参数)

在参数个数不明确、需要根据用户传递的数量来确定的时候,可以使用可变参数来实现。可变参数可以通过*或**来表示(一般约定俗成使用*args或者**kwargs)。*args用于接收未定义的位置参数,并且存放到一个元组中;**args用于接收未定义的关键字参数,并且存放到一个字典中

def get_sum(*args):    #定义了一个可变参数
    print(args) 
get_sum(1,2)              #以元组形式输出1,2
get_sum(1,2,3)           #以元组形式输出1,2,3
get_sum()                   #也可以不传递任何参数

#使用可变参数时经常会涉及装包与拆包操作,赋值时是装包过程,调用时是拆包过程
nums = (12,4,5,1)   #这里传递了一个元组作为参数,在传参时使用*号调用就完成了拆包
my_sum(*nums)

*y = 4,6,8
print (y)    #结果是[4,6,8]

t1=(9,4,8,6)
x,*y = t1
print (x,y)  #x=9,y=[4,8,6]


def show_book(**args):
    print(args)
    
show_book(bookname='西游记',author='吴承恩')  #两个*号的参数必须传递字典类型的数据
book = {bookname='红楼梦',author='曹雪芹'}
show_book(**book)     #将已有字典拆包传递给函数


4、命名参数(关键字参数

如果是在可变参数后面还存在参数,那么在调用函数的时候必须使用命名参数来传递数据

def test_fun(a,b,c=3,*args,name):
    print(a,b,c)
    print(args)
    print(name)

test_fun(1,2,4,5,6,7,name="tanglu")
# 输出结果
1 2 4
(5, 6, 7)
tanglu


四、Python函数顺序

如果一个函数中同时存在多种不同类型的参数,其书写顺序要按照位置参数 > *args > 默认参数 > **kwargs这样的顺序书写,即:

· 位置参数需要放在最前面,关键字参数放后面

· 如果存在可变参数,需要放在普通参数和默认值参数的后面

· 如果同时存在*args和**kwargs两种可变参数,*args在前面

# 书写顺序示例
# def abc(普通参数,默认值参数,*参数,**参数)
def abc(a,name='tanglu',*args,**kwargs):
  print(a)
  print(name)
  print(args)
  print(kwargs)
abc(100,"唐路",1,2,3,x=100,y=200)  

# 100
# 唐路
# (1, 2, 3)
# {'x': 100, 'y': 200}


五、Python函数的返回值

· 返回值的作用就是将函数执行后返回的结果给其他地方调用,通常是返回给一个变量(有点像把Docker容器中的端口暴露出来给系统其他服务使用的感觉)

· 在Python中通过 return 语句来返回值,如果未定义return或者定义了return但是没有传递值的话,最终都会返回None

· 在函数体中return之后的代码以及函数本身都会被结束

· 如果函数有多个返回值,这些值将被保存在一个元组中

def func(a,b):
  return a + b
sum = func(10+5)   #将return的返回值传递给变量,方便后面调用,否则这个返回值没有东西接收
print(sum)


def func(a,b):
  print(123)
  return        #程序停止,后续代码不再继续
  print(456)
result = func()
print(result)    #返回123和None,后面的print(456)因为遇到了return不会再执行
  
  
  
#一个函数中的代码块可能存在多个任务,如果想指定最终返回结果,需要用return
def worker(a, b, c):
    x = a + b  #函数完成了动作1,即a + b
    y = x * c  #函数完成了动作2,即x * c
    return y    #指定函数只返回动作2的结果
    
num = worker(1, 2, 3)  #需要使用一个变量接收函数的返回值
print(num)  #返回为9,(a+b)*c


六、Python函数变量的作用域

在函数中定义的变量默认为局部变量 ,在函数A中定义了变量var1,在函数中B也可以定义一个变量var1。如果要让函数调用或者修改全局变量,需要使用关键词global。只有内存地址不可变的数据类型才需要添加global关键词,包括int、str、float、bool、tuple,而对于可变类型的数据(数据发生变化但是内存地址不变)可以不用加global。函数在引用全局变量时,变量一定要先于引用前进行定义,否则会出现找不到变量的错

b = 5
def test1():
  a = 10
  print(a)

def test2():
  a = 20 
  print (a)

def test3()
  global b  #声明全局变量
  b = 10  #修改全局变量b的值

test1()  #输出10
test2()  #输出20


2、函数可以嵌套函数,内部函数可以引用外部函数的变量,如果要修改外部函数的变量需要通过nonlocal关键词修改,在引用外部函数变量或者全局变量时内部就不能再定义同样的变量,否则会冲突。在嵌套函数结构中,如果内部函数引用了外部函数的变量且最终返回值是内部函数,那么属于闭包

def outer():
  a = 100
  def inner():
    b = 200
    print('我是内部函数:',b)
    b += a            
    print(b)
  print(a)
  inner()

outer()


3、一个函数接收另一个函数作为参数,那么这个函数是高阶函数


七、函数参数解包

使用*或者**可以对传入的参数进行解包操作,这样就可以将列表或者字典拆开,然后里面的每个元素都作为函数的参数进行传递

# student_info = ['stu1','stu2','stu3','stu4','stu5','stu6','stu7','stu8']
# def func(*args):
#   print(args)
# func(*student_info)
  
#对字符串解包
string = "abc"
def abc(a,b,c):
    print(a)
    print(b)
    print(c)
abc(*string)  #输出a,b,c

#对列表\元组\集合解包时元素要和参数个数对应,不能多也不能少
list = [1,2,3]
def abc(a,b,c):
    print(a)
    print(b)
    print(c)
abc(*list)

#对字典解包的话输出的是key,如果需要输出value的话是用两个星号**,并且定义的参数要和字典里的key是一样的
dic = {"name":"tanglu","age":18,"height":175}
def abc(a,b,c):
    print(a)
    print(b)
    print(c)
abc(*dic)   #输出name,age,height

dic = {"name":"tanglu","age":18,"height":175}
def abc(name,age,height):
    print(name)
    print(age)
    print(height)
abc(**dic)   #输出tanglu,18,175


八、Python中的程序入口函数(main函数)

main函数是Python代码的执行入口,Python会从main函数标记的位置开始执行程序。这个入口在一个程序中通常是唯一的,用于说明整个程序是从哪个文件或者哪个部门开始执行。虽然Python没有严格要求必须存在代码入口,但是为了规范的话建议开启。在Python程序中对于main函数的写法格式如下

if __name__ == '__main__':

评论