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) #

# 可以将函数名赋值给其它变量名

h = f

print(h(16, 16)) # 256

(3)表达式调用

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

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

def f1(x, y):

return x + y

print(f1(11, 22),type(f1(11, 22))) # 33

def f2(a, b):

res1 = a + b

res2 = a * b

return res1, res2

print(f2(3, 3),type(f2(3, 3))) # (6, 9)

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

Copyright © 2088 1986世界杯_意大利世界杯 - zlrxcw.com All Rights Reserved.
友情链接