11. 函数的参数

1. 函数的概念与定义

1.1 概念

循环的本质:在相同的地方反复执行相同的代码

函数的本质:在不同的地方反复执行相同的代码

1.2 语法

def 函数名(参数1,参数2):
    """函数的注释"""
    函数体代码
    return 返回值
1. def:是定义函数的关键字
2. 函数名:函数名类似于变量名,指代函数体代码,
         命名与变量名一致(字母、数字、下划线、数字不能开头;下划线形式、驼峰体形式)
         类似于数学函数中的 h(x)的h,  f(x)的f
3. 括号:定义函数的时候,函数名后面一定要有括号
4. 参数:类似于使用函数的时候,给函数内部传递的数据,可以不写,或者单个、多个
        有点像数学函数中f(x)的x
5. 冒号:定义函数也需要有缩进的代码块
6. 函数的注释:用于解释函数的主要功能、使用说法等说明性文字
7. 函数体代码:函数的核心功能
            有点像数学函数中f(a)右侧的函数式  f(a,b) = a + b
8. return:后面跟什么,函数执行完成后就会返回什么

定义函数不会执行函数体代码,但是会检测语法

# 1.函数的基本定义
def f1():
    a = 1 +1
f1()  
print(f1())  # None

# 2.有一个参数但是没有返回值的函数
def f2(name):
    b = 1 + 2
f2('messi')  #
print(f2('messi'))  # None

# 3.有多个参数但是没有返回值
def f3(x, y):
    res = x + y
# 函数调用的时候,定义几个参数就必须传几个参数
f3(333, 666)
print(f3(333, 666))  # None

# 4.有参数有返回值的函数
def f4(a, b):
    res2 = a * b
    return res2
print(f4(9, 9))  # 81

1.3 函数的调用

(1)直接调用

根据函数名调用函数

(2)间接调用

用新的变量名来存储原本函数的内存空间地址,然后再调用原本的函数

def f(x, y):
    return x * y
print(f)  # <function f at 0x0000024F50773E20>
# 可以将函数名赋值给其它变量名
h = f
print(h(16, 16))  # 256

(3)表达式调用

在函数的返回值中如果只有一个返回值就是该值本身的类型

如果有多个返回值,返回的结果是一个元组---解压赋值

def f1(x, y):
    return x + y
print(f1(11, 22),type(f1(11, 22)))  # 33 <class 'int'>

def f2(a, b):
    res1 = a + b
    res2 = a * b
    return res1, res2
print(f2(3, 3),type(f2(3, 3)))  # (6, 9) <class 'tuple'>

1.4 函数的返回值

函数体代码里面写return相当于循环体代码里面写break,遇到了就会立刻结束函数和循环的执行

如果写的是变量名就返回变量名指向的值

函数的返回值可以被其它变量接收

函数的返回值可以被其它函数接收

def f1(a, b):
    return a + b
def f2(x, y):
    return x * y
print(f2(f1(1,2), 10))  # 30

1.5 函数作为参数

def get_name_pwd():
    name = input("请输入名字: ")
    pwd = input('请输入密码')
    return name, pwd


def login():
    login_name, login_pwd = get_name_pwd()
    if login_name == 'messi' and login_pwd == '001':
        print('登录成功')
    else:
        print('登录失败')


def regi():
    regi_name, regi_pwd = get_name_pwd()
    print(f'用户{regi_name}注册成功')
-------------------------------------------------------------------

choice = """
***功能菜单***
1.注册
2.登录
"""
func_dict = {
    '1': regi,  # 函数名regi即函数regi的内存地址
    '2': login  # 函数名login即函数login的内存地址
}
while True:
    print(choice)
    id = input('请输入功能id:')
    if id not in func_dict:
        print('你的输入有误')
        continue
    f1 = func_dict.get(id)
    # f1可以是regi的内存地址,也可能是login的地址
    f1()
之前的写法
while
True: print(choice) id = input("请输入功能ID :>>>> ").strip() if id == '1': regi() elif id == 2: login()

2. 函数的参数

2.1 形参与实参

形参:函数在定义阶段括号内写的参数,称之为形式参数

实参:函数在调用阶段括号内写的参数,称之为实际参数

形参类似于变量名,实参类似于变量值

在调用函数的时候传入实参,会与形参临时绑定,函数运行结束之后自动解除绑定

def f1(x, y):  # x和y就是f1函数的形参
    print(x + y)

f1(11, 22)  # 11和22就是f1函数的实参

2.2 位置参数和关键字参数

位置参数

位置形参:在函数定义阶段括号内从左往右依次填写的变量名

位置实参:在函数调用阶段括号内从左往右依次传入的数据

在调用的时候参数个数要相等,顺序不能乱

关键字参数

出现在实参中,用变量的方式给函数传参,与顺序无关

def f1(x, y):
    print(x + y)
f1(x=11, y=22)  # 33
f1(y=2, x=3)  # 5
位置参数与关键字参数混用
def
f1(x, y): print(x + y) f1(y=111, 222) # 报错,关键字参数必须放在位置参数的后面 f1(333, x=444) # 报错,形参只能指向一个实参,形参x重复绑定值

2.3 默认参数

在函数的定义阶段给变量名赋一个初始的值

如果该变量被传入新的值,则初始值会被新值覆盖

如果该变量没有被传入新的值,则还是使用初始的默认值

默认参数必须放在位置参数后面

def player(name, num, club='psg'):
    print(f'球员{name}号码{num}球队{club}')
player('messi', 1)
player('kylian', 2)
player('ronaldo', 3,'realmadrid')
# 球员messi号码1球队psg
# 球员kylian号码2球队psg
# 球员ronaldo号码3球队realmadrid

默认参数的特殊情况

a = []
def app_element(num):
    a.append(num)
    return a
print(app_element(1))  # [1]
print(app_element(2))  # [1, 2]
print(app_element(3))  # [1, 2, 3]
----------------------------------------------------------
def app_element(num, a=[]):
    a.append(num)
    return a
# 因为列表是可变数据类型所以 在每次添加新的元素后影响到的都是原本的列表
# 列表中添加 1 2 3 ---> [1,2,3]
print(app_element(1))  # [1]
print(app_element(2))  # [1, 2]
print(app_element(3))  # [1, 2, 3]
def app_element(num, a=None):
    if not a:
        a = []
    a.append(num)
    return a

print(app_element(1))  # [1]
print(app_element(2))  # [2]
print(app_element(3))  # [3]

2.4 可变长参数

需求:定义一个函数,无论穿多少位置实参都可以正常执行

可变长位置参数

*号在形参中,可以接收多余的位置参数,组成元组的形式赋值给*号后后面的变量名

推荐写法  *args

def f1(a, b, *args):
    print(a, b)  
    print(args)  
f1(1, 2, 3, 4)
# 1 2
# (3, 4)

*号是压缩与解压的意思

a = [1, 2, 3]
print(a)  # [1, 2, 3]
print(*a)  # 1 2 3
def f1(name, num):
    print(f'球员{name}')
    print(f'号码{num}')
info = ['messi', '001']
f1(*info)
# 球员messi
# 号码001

**号在形参中,用于接收多余的关键字参数,组成字典的形式赋值给**后面的变量名

推荐写法   **kwargs

def add(x, y, *args, **kwargs):
    print(x, y)
    print(args)
    print(kwargs)
add(1, 2, 3, 4, 5, a=666, b=999)
# 1 2
# (3, 4, 5)
# {'a': 666, 'b': 999}

2.5 命名关键字参数

2.5.1 概念

想要限定函数的调用者必须以key=value的形式传值

Python3提供了专门的语法:

在定义形参时,用 * 号作为一个分隔符号,* 号之后的形参称为命名关键字参数
对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值
def add(x, y, *, z):
    print(z)    
add(11, 22, z=33)  # 33

没以key=value传值会报错

没传值也会报错

def handle_info(name, age, *, gender, hobby):  # gender,hobby为命名关键字参数
    pass


# 正确调用
handle_info('messi', 37, gender='male', hobby='soccer')

# 未使用关键字进行传值
handle_info('messi', 37, male, soccer)  # NameError: name 'male' is not defined. Did you mean: 'False'?

# 传少了值
handle_info('messi', 37, gender='male')  # TypeError: handle_info() missing 1 required keyword-only argument: 'hobby'

2.5.2 命名关键字参数默认值

命名关键字参数也可以有默认值,从而简化调用

def handle_info(name, age, *, hobby='soccer', gender):
    print(f'Name:{name}, Age:{age}, Hobby:{hobby}, Gender:{gender}')

handle_info('messi', 20, gender='male')
# Name:messi, Age:20, Hobby:soccer, Gender:male

需要强调的是,hobby不是默认参数,gender也不是位置参数

因为二者都在 * 号之后,所以都是命名关键字参数,形参hobby='soccer属于命名关键字参数的默认值,因而即便是放到形参gender之前也不会有问题

另外,如果形参中已经有了一个 * args了,命名关键字参数就不再需要一个单独的 * 作为分隔符号

def handle_info(name, age, *args, hobby='soccer', gender):
    print(f'Name:{name}, Age:{age}, Args:{args}, Hobby:{hobby}, Gender:{gender}')

# hobby与gender仍为命名关键字参数
handle_info('messi', 20, 1, 2, 3, 4, 5, 6, gender='male')
# Name:messi, Age:20, Args:(1, 2, 3, 4, 5, 6), Hobby:soccer, Gender:male

2.5.3 函数内判断

在定义了**kwargs参数后,函数调用者就可以传入任意的关键字参数key=value

如果函数体代码的执行需要依赖某个key,必须在函数内进行判断

def regi(name, age, **kwargs):
    if 'gender' in kwargs:  # 有gender参数
        pass
    if 'hobby' in kwargs:  # 有height参数 
        pass

 

 

 

 

 

 

 

 

                                                            

 

posted @ 2024-07-25 18:38  hbutmeng  阅读(6)  评论(0编辑  收藏  举报