day10
1.今日内容
1.函数介绍
什么是函数
为何要用
如何用函数:先定义,后调用
函数-------------》工厂
函数名 地址
参数 原材料
函数体代码 工厂的流水线
返回值 工厂的产品
2.函数的返回值
3.函数的参数
2.函数的基本使用
'''
1、什么是函数
函数就是盛放代码的容器,把实现某一功能的一组代码丢到一个函数中
就做成了一个小工具
具备某一功能的工具-》函数
事先准备工具的过程-》函数的定义
遇到应用场景拿来就用-》函数的调用
2、为何要用函数
在没有用函数之前面临的问题:
1、代码冗余,程序组织结构不清晰、可读性差
2、扩展性差
3、如何用函数
原则:先定义、后调用
定义函数的语法:
def 函数名(参数1,参数2,参数3,...):
"""
文档注释
"""
代码1
代码2
代码3
return 返回值
如何调用函数:
函数名(1,2,3)
'''
# 一 先定义、后调用
def func():
print("start...")
print("xxx")
print("stop...")
func()
func()
func()
# 二:函数在定义阶段发生的什么事情
# 定义函数不执行函数体代码,但是会检测函数体语法
x = 100
print(x)
def func(): # func=函数的内存地址
print("start...")
x
# if True
# print('ok')
print("xxx")
print("stop...")
# print(func)
func()
# 三:函数在调用阶段发生的什么事情
# 先通过函数名找到函数的内存地址,然后函数的内存地址()会触发函数体代码的运行
def func(): # func=函数的内存地址
print("start...")
print("xxx")
print("stop...")
func()
x = 10
x()
3.小案例
案例1
def foo():
print('from foo')
bar()
foo()
案例2
def bar():
print('from bar')
def foo():
print('from foo')
bar()
foo()
案例3
def foo():
print('from foo')
bar()
def bar():
print('from bar')
foo()
4.函数的返回值
res = input('username>>: ') # res = "egon"
print(res)
res = print("hello")
print(res) # print没有返回值
l = [11, 22, 33]
res1 = l.pop()
res2 = l.remove(11)
print(res1) # 有返回值
print(res2) # 没有返回值
# 用return控制函数的返回值:
# 函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的
# 值当做本次调用的结果返回,具体来说,函数的返回值又分为三类
# 1、return 值:返回的就是该值本身
# 2、return 值1,值2,值3:返回的是一个元组
# 3、函数内可以没有return,或就一个return后没有值:返回的是None
def func():
print("start")
# return 123,"aa",[1,2,3]
# return
print("end")
res = func()
print(res)
5.小案例
def max2(x, y):
# x = 3.3
# y = 5.5
if x > y:
return x
else:
return y
res = max2(3.3, 5.5)
print(res * 12)
l1 = [1, 2, 3]
6.函数定义与调用的三种格式
1.函数定义
# 一 定义函数的三种形式
# 1.1 无参
def func():
print('=====')
print('hello')
print('=====')
func()
# 1.2 有参
def max2(x, y):
if x > y:
print(x)
else:
print(y)
max2(10, 11)
def login(user, pwd):
# user = input("u>>>: ")
# pwd = input("p>>>: ")
if user == 'egon' and pwd == '123':
print('ok')
else:
print('error')
login('egon', '123')
# 1.3 空函数
def func():
pass
...
def login():
pass
def register():
pass
choice = input('>>>: ')
if choice == '1':
pass
elif choice == '2':
register()
2.函数调用
# 二 调用函数的三种形式
# 2.1 语句形式
def login():
user = input("u>>>: ")
pwd = input("p>>>: ")
if user == 'egon' and pwd == '123':
print('ok')
else:
print('error')
login()
# 2.2 表达式形式
res = input(">>: ")
def max2(x, y):
if x > y:
return x
else:
return y
sal = max2(30, 40) * 12
# 2.3 可以把函数调用当做参数传给另外一个函数
def max2(x, y):
if x > y:
return x
else:
return y
res = max2(max2(10, 20), 30)
print(res)
7.形参与实参的介绍
# 一 函数参数分为两大类:
# 1.形参:在函数定义阶段括号内定义的变量名,称之为形式参数,简称形参
# 2.实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参
# 形参与实参的关系是:
# 在调用函数时,实参的值会绑定给形参名,然后可以在函数内使用,函数调用完毕后,解除绑定
def func(x, y):
# x=1
# y=2
print(x + y)
m = 1
n = 2
func(m, n)
8.函数参数part1
# 一 函数参数分为两大类:
# 1、形参:在函数定义阶段括号内定义的变量名,称之为形式参数,简称形参
# 2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参
# 形参与实参的关系是:
# 在调用函数时,实参的值会绑定给形参名,然后可以在函数内使用,函数调用完毕后,解除绑定
def func(x, y):
# x=1
# y=2
print(x + y)
m = 1
n = 2
func(m, n)
# 二:参数详解
# 2.1 位置形参::在函数定义阶段按照从左到右的顺序依次定义的形参,称之为位置形参
# 特点:必须被传值,多一个不行少一个也不行
def func(x, y):
print(x + y)
func(1, 2)
func(1, 2, 3)
func(1, )
# 2.2 默认形参:在函数定义阶段就已经为某个形参赋值了,称之为默认形参
# 特点:在函数定义阶段就已经赋值了,意味着在调用阶段可以不用为其赋值
# 2.3 位置实参:在函数调用阶段按照从左到右的顺序依次传入的值,称之为位置实参
# 特点:按照顺序与形参一一对应
def func(x, y):
print(x)
print(y)
func(1, 2)
func(2, 1)
# 2.4 关键字实参:在函数调用阶段按照key=value的格式传入的值,称之为关键字实参
# 特点:可以打乱顺序,但是仍然能够为指定的形参赋值
# ps:可以混用位置实参与管家腻子实参,但是
# 1、位置实参必须在关键字实参前
# 2、不能为同一个形参重复赋值
def func(x, y):
print(x)
print(y)
func(y=2, x=1)
func(1, y=2)
func(y=2, 1)
func(1, 2, y=3)
9.函数参数part2
# 2.2 默认形参:在函数定义阶段就已经为某个形参赋值了,称之为默认形参
# 特点:在函数定义阶段就已经赋值了,意味着在调用阶段可以不用为其赋值
# ps: 可以混用位置形参与默认形参,但是位置形参必须在前
def func(x, y=2):
print(x)
print(y)
func(1, 3)
func(1)
def register(name, age, gender="male"):
print(name, age, gender)
register("李铁蛋", 38)
register("王全蛋", 19)
register("赵银蛋", 28)
register("lili", 18, "female")
# 默认形参需要注意的问题是:
# 1、默认形参的值只在函数定义阶段被赋值一次
# 2、默认形参的值通常应该是不可变类型
# 案例1
m = 100
def func(x, y=m): # y -> 100的内存地址
print(x, y)
m = 200
func(1)
# 案例2
m = [11, 22, ]
def func(x, y=m): # y -> [11,22,]的内存地址
print(x, y)
# m = 200
m.append(33)
func(1)
# def register(name, x, hobbies=[]):
# hobbies.append(x)
# print("%s的爱好是%s" % (name, hobbies))
#
#
# register('egon', 'read')
# register('liu', 'chou')
# register('hxx', 'tang')
def register(name, x, hobbies=None): # hobbies = []内地址
if hobbies is None:
hobbies = []
hobbies.append(x)
print("%s 的爱好是 %s" % (name, hobbies))
register("egon", 'read')
register("liu", 'chou')
register("hxx", 'tang')
10.函数参数part3(可变长参数)
# 2.5 *与**在形参与实参中的应用
# 可变长的参数:可变长指的是在函数调用阶段,实参的个数不固定,而实参是为形参赋值的,所以对应着必须要有一种特殊格式的形参
# 能用来接收溢出的实参
# 形参中带*:*会接收溢出的位置实参,然后将其存成元组,然后赋值给紧跟其后的变量名
def func(x, *args): # y=(2, 3, 4, 5, 6)
print(x)
print(args)
func(1, 2, 3, 4, 5, 6)
def my_sum(*args):
res = 0
for num in args:
res += num
print(res)
my_sum(1, 2, 3, 4, 5)
my_sum(1, 2)
# 形参中带**:**会接收溢出的关键字实参,然后将其存成字典,然后赋值给紧跟其后的变量名
def func(x, **kwargs): # y = {'a':1,'b':2,'c':3}
print(x)
print(kwargs)
func(1, a=1, b=2, c=3)
func(1, 2, 3, a=1, b=2, c=3) # 报错
# 实参中带*:*后跟的必须是一个可以被for循环遍历的类型,*会将实参打散成位置实参
def func(x, y, z):
print(x)
print(y)
print(z)
func(*[11, 22, 33]) # func(11,22,33)
func(*"hello") # func("h","e","l","l","o")
# 实参中带**:**后跟的必须是一个字典,**会将实参打散成关键字实参
def func(x, y, z):
print(x)
print(y)
print(z)
func(**{"x": 1, "y": 2, "z": 3}) # func(z=3,x=1,y=2)
def index(x, y, z):
print(x, y, z)
def wrapper(*args, **kwargs): # args = (1,2,3,4,5,6,7) kwargs={"a":1,"b":2,"c":3}
# print(args)
# print(kwargs)
index(*args, **kwargs) # index(*(1,2,3,4,5,6,7),**{"a":1,"b":2,"c":3})
# index(1,2,3,4,5,6,7,a=1,b=2,c=3)
# wrapper(1,2,3,4,5,6,7,a=1,b=2,c=3)
# wrapper(1,2,3)
wrapper(1, z=3, y=2)