python基础之函数

python基础之函数

一、什么是函数

函数可以理解为存放代码的容器,它是有功能的工具
# 函数是一种仅在调用时运行的代码块,我们可以用参数传递到函数中,函数可以把数据作为结果返回
# 优点:简介代码 增加开发效率
我们可以使用函数: 1先 创建或者定义函数 2后 调用函数

二、定义函数

1.函数必须 '先定义,后调用'
		函数的定义相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名可以对这段代码进行引用。没有事先定义函数,则无法调用。
2.函数的语法
def 函数名(参数1,参数2,...):
  '''函数注释'''
  函数体代码
  return 返回值
"""
1.def:定义函数的关键字
2.函数名:命名等同于变量名,函数名只想函数内存地址,是对函数体代码的引用,函数名应该反映出函数的功能
3.参数:括号内定义参数,参数可有可无,主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释:描述函数的功能
5.函数体代码:是整个函数的核心,主要取决于程序员的编写
6.return:使用函数之后可以返回给使用者的数据,可有可无
"""

三、函数的分类

1.空函数
函数代码体为pass 或者... 称之为空函数
# 空函数主要用于程序设计的开始,功能框架的搭建
def register():
  """注册功能"""
  pass

2.有参函数
		参数是函数的调用者想函数体传值的媒介,若函数体代码逻辑依赖外部传来的参数时 需要参数
# 如
def my_min(x,y):
    res = x if x < y else y
    return res
3.无参函数
    定义函数的时候括号内没有参数
# 如
def name_pwd():
    username = input('please input username:').strip()
    password = input('please input password:').strip()
    return(username, password)

四、调用函数与函数的返回值

1.调用函数

函数的使用分为定义阶段与调用阶段,
1定义函数时  只检测语法,不执行函数体代码
2调用函数时  函数名+() 即为函数调用,只用定义函数之后调用函数时才会执行函数体代码

# 定义函数
def p_index():
    print('from index function')
   
# 调用函数
p_index()

2.函数返回值

1.什么时候函数的返回值
    调用函数之后返回给调用者的结果,需要用到 关键字 return
2.如何获取返回值
    变量名 赋值符号 函数的调用
  res = func()  # 先执行func函数 然后将返回值赋值给变量res
3.函数返回值的多种情况
  1)函数体代码中 没有 return 默认返回 None
  2)函数体代码中   有 return 后面没写任何东西  返回 None
  3)函数体代码中   有 return 后面写something 返回something
  4)函数体代码中   有 return 后面有多个数据值  返回 包含数据值的元组
  5)函数体代码中 遇到 return 立刻结束代码体

五、函数的参数

1.形式参数与实际参数

1.形式参数'形参'
    定义函数阶段 括号内填写的参数,形参本质就是一个变量名,用来接收外部传来的值
2.实际参数'实参'  
    调用参数阶段 括号内填写的参数,可以是常量、变量、表达式、或者三者的组合:
"""
形参与实参的关系
    形参类似于变量名,在函数定义阶段可以随便写,最好见名知意
def register(name,pwd):
    pass
	
    实参类似于数据值,在函数调用阶段 实参(值)与形参(变量名)临时绑定,这种绑定关系只在函数调用时生效,在调用结束后解除
	
    形参与实参在函数调用阶段动态绑定 在函数结束阶段动态解除
    register('jason',123)   形参name与jason绑定 形参pwd与123绑定
"""

2.位置参数

positional arguments

位置即顺序,位置参数指的是按从左到右定义的参数,需要从两个角度去看:
1.位置形参
    在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值

    函数定义阶段括号内从左往右依次填写的变量名
def func1(a,b,c):pass
  # a b c 为位置形参,三者都必须被传值,否则调用函数的时候会报错
 
# 举例1:
def register(name,age,sex): #定义位置形参:name,age,sex,三者都必须被传值
    print('Name:%s Age:%s Sex:%s' %(name,age,sex))

register() #TypeError:缺少3个位置参数

2.位置实参
     在调用函数时,按照从左到右的顺序依次定义实参,称为位置参数,凡事按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
     函数调用阶段括号内从左往右依次填写的数据值
  func1(1,2,3)  # 对应关系为 a = 1,b = 2, c = 3
  # 1 2 3 为位置实参
  
    # 举例2:
def func1(a, b):
    print(a, b)

func1(1, 2)  # 按照位置一一对应传值
func1(1)  # 少一个不行
func1(1, 2, 3)  # 多一个也不行

  """
 位置传参 需要 按照位置一一传值
  """ 

3.关键字参数

  key=value的形式
  
  1.调用参数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但任然能为指定为形参赋值
  关键字传参一定要跟在位置传参的后面否则报错
  
  # 举例2:
def func1(a, b):
    print(a, b)

func1(b=1, a=2)  # 关键字传参(指名道姓的传)

func1(b=1, 2)  # 关键字传参一定要跟在位置传参的后面否则报错
func1(2, b=1)  # 可以

2.同一个形参在调用的时候不能多次赋值,不然会报错

func1(1, a=2, b=3)  # 报错TypeError: func1() got multiple values for argument 'a'

3.实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名
# 举例3:
def func1(a, b):
    print(a, b)
    
name = 'jason'
pwd = 123
func1(name, pwd)  
func1(a=name, b=pwd)  

注意:

1 关键字传参一定要在位置传参的后面(越短的越简单的越靠前,越长的越复杂的越靠后)
2 同一个形参在调用的的时候不能多次赋值
3 实参没有固定的定义,可以传数据值,也可以传绑定了的数据值的变量名

4.默认参数

    默认参数的本质 : 关键字形参,定义时值就已经给了 用户可以不传
    也就是,当函数有多个参数时,需要将经常改变的参数定义成位置参数,而将值改变较少的参数定义为默认参数
  
# 举例一:
 # 错误
def register(name, age=18, gender) 默认参数的定义也遵循短的简单的靠前,长的靠后 这样会报错
 # 正确
def register(name, age, gender='male'):  # 函数定义阶段直接给形参赋值,可以设定默认参数
    print(f"""
 	----------info------------
  	name:{name}
 	age:{age}
 	 gender:{gender}
	--------------------------
  	""")
  
register('jason', 18, 'male')
register('jack', 18)
register('lucy', 18, 'female')
register('lulu', 18, gender='female')

注意:

1.默认参数必须在位置参数之后
2.默认参数的值仅仅在函数定义阶段被赋值一次

4.可变长的形参

    如果在最后一个形参名前面加*号,那么在调用函数的时候,溢出的位置实参,都会被接收,一元组的形式保存下来赋值给该形参		
  1.在函数定义阶段,语法结构
def 函数名(*形参/**形参/组合):  
    函数体代码
  
  2.一个*号:*号在形参中,用于接收多余的位置参数,组织成元组赋值给*号后面的变量名
  1)(*a)形式
# 案例一
def func1(*a):
    print(a)
func1()  # ()
func1(1)  # (1,)
func1(1,2)  # (1,2)
func1(1,2,3,4,5)  # ()

  2)(b,*a)形式
# 案例二
def func2(b,*a):
    print(a,b)
func2()  # 函数至少需要一个参数给到b,不然会报错
func2(1)  # () 1
func2(1,2,3,4) # (2,3,4) 1

# 案例二 *形参,关键字参数会报错
def index(*a,b): 
    pass
index(1,2,3,4,5)  # TypeError: index() missing 1 required keyword-only argument: 'b'

 4.两个**号 :**号在形参中,用于接收多余的关键字参数,组织成字典的形式赋值给**号后面的变量名
  1)(**k)形式
# 案例四 
  (**k)形式
def func4(**k):  
    print(k)
    
func3()  # {}
func3(a=1)  # 1 {}
func3(a=1,b=2 ,c=3)  # 1 {'a':1,'b':2','c':3} 

  2)(a, **k)形式
def func4(a,**k):
    print(a, k)

func4()  # 报错,函数至少需要一个参数给到a
func4(a=1)  # 1 {}
func4(a=1, b=2, c=3)  # 1 {'b': 2, 'c': 3}
func4(a=1, b=2, c=3, x='jason', y='kevin')  # 1 {'b': 2, 'c': 3, 'x': 'jason', 'y': 'kevin'}

  3)(*a, **k)形式
# 案例五
def func5(*a,**k):
    print(a, k)
 
func5()  # () {}
func5(1,2,3)  # (1,2,3) {}
func5(a=1,b=2 ,c=3)  # () {'a':1,'b':2','c':3}
func5(1,2,3,a=1,b=2 ,c=3)  # (1,2,3) {'a':1, 'b':2, 'c':3}


"""
由于* 和**在函数的形参中使用频率很高,后面跟的变量名使用推荐
    *args
    **kwargs
def index(*args, **kwargs):pass
"""

5.可变长的实参

 函数调用阶段
  
# 案例一:
将列表中三个数据值取出来传给函数的三个形参
def index(a, b, c):
    print(a, b, c)
l1 = [11, 22, 33]
t1 = (33, 22, 11)
s1 = 'tom'
se = {123,321,222}
d1 = {'name':'jason','pwd':123,'age':12}
  # 方式一
index(l1[0], l1[1], l1[2])
 1.函数名(*实参)  # 一个*号
  *在实参中,类似于for循环 将所有循环遍历出来的数据按照位置参数一次性传给函数
 # 方式二 即用*号
index(*l1)  # 等价于 index(11, 22, 33)
index(*t1)  # 等价于 index(33, 22, 11)
index(*s1)  # 等价于 index('t', 'o', 'm')
index(*se)  # 等价于 index(321, 123, 222)
index(*d1)  # 等价于 index('name','pwd''age')

2. 函数名(**实参)  # 两个**号
         **在实参中,将字典打散成关键字参数的形式传递给函数
# 案例二
def index(name,pwd,age):
    print(name,pwd,age)
d1 = {'name':'tom', 'pwd':123, 'age':12}
index(name=d1.get('name'),pwd=d1.get('pwd'),age=d1.get('age'))
index(**d1)  # index(name='jason',pwd=123,age=12)


3.(*args, **kwargs)形式
def index(*args, **kwargs):
    print(args)  # (11, 22, 33, 44)
    print(kwargs)  # {}

index(*[11,22,33,44])  # index(11, 22, 33, 44)
index(*(11,22,33,44))  # index(11, 22, 33, 44)

6.(了解)命名关键字参数

def index(name,gender='male',*args,**kwargs):
    print(name, args, gender, kwargs)
  
1.形参必须按照关键字参数传数,必须按照命名关键字参数
2.只能将该形参放在*形参 后面
  

综上所述,所有参数都可以任意组合使用,但定义顺序必须是

位置参数、默认参数、*args、命名关键字参数、**kwargs

posted @ 2022-10-10 00:19  Duosg  阅读(58)  评论(0编辑  收藏  举报