**今日内容:**
函数基础
函数参数
形参与实参
位置参数
关键字参数
默认参数
*
**
**1 什么是函数**
函数是盛放代码的容器:把实现某一功能的代码放到一个函数内就制造一个工具
**2 为何要用函数**
没有用函数之前程序的问题:
1、代码冗余、程序的可读性差
2、可拓展性差
(写好程序重复复制粘贴代码,想修改非常麻烦,全部修改)
**3 如何用函数**
函数-》实现某一功能的工具
函数定义-》事先准备工具的过程
函数调用-》遇到应用场景,拿来就用
**4** **函数的使用原则:先定义、后调用**
**一 定义函数**
**语法**
def 函数名(参数1,参数2,参数3,...):
"""函数注释"""
函数体
(代码1,
代码2,
代码3)
return 返回值
**def: 定义函数的关键字;**
函数名(工厂名-地址):函数名指向函数内存地址,是对函数体代码的引用。
函数的命名应该反映出函数的功能;
括号:括号内定义 参数(给工厂运输的原材料),参数是可有可无的,且无需指定参数的类型;
冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;
"""文档描述""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,
从而增强函数的可读性;
函数体:由语句和表达式组成;函数体代码(工厂加工的流水线)
return 值:定义函数的返回值,return是可有可无的。(工厂产出的产品)
**定义函数发生的事情:**
(1)申请内存空间,把函数体代码存起来
(2)将函数的内存地址绑定函数名
**定义一个注册函数**
def register():
inp_user = input("请输入您的账号:").strip()
inp_pwd = input("请输入您的密码:").strip()
inp_money = input("请充值:").strip()
with open(‘db.txt‘, mode=‘at‘, encoding=‘utf-8‘) as f:
f.write(‘%s:%s:%s\n‘ % (inp_user, inp_pwd, inp_money))
x = 10
print(x)
print(register)
**二 调用:**
(1) 根据函数名函数的内存地址
(2) 函数的内存地址()触发函数体代码的运行
register()
register()
register()
**三 函数定义阶段**:只检测语法不执行代码
def func():
print(‘hello1 #语法错误,直接报错
qwert #逻辑错误,事先未定义函数,这里不会报错,运行之后才知道
func() #NameError:name ‘qwert‘ is not defined
**四 函数调用阶段**:才会执行函数体代码
def foo():
print(‘from foo‘)
bar()
def bar():
print(‘from bar‘)
foo()
结果显示:
from foo
from bar
**函数定义三种形式**
**1、有参函数**
例1:
def foo(x,y):
print(x,y)
foo(1,2)
例2:
def my_min(x,y):
res=x if x < y else y
return res
**2、无参函数**
例1:
def foo():
print(‘hello‘)
foo()
例2:
def interactive():
user=input(‘user>>: ‘).strip()
pwd=input(‘password>>: ‘).strip()
return (user,pwd)
**3、空函数**
def foo():
pass
按照在程序出现的形式和位置,可将函数的调用形式分为三种:
**#1、语句形式:**
foo()
**#2、表达式形式:**
m=my_min(1,2) #将调用函数的返回值赋值给x
n=10*my_min(1,2) #将调用函数的返回值乘以10的结果赋值给n
**#3、函数调用作为参数的形式:**
# my_min(2,3)作为函数my_min的第二个参数,实现了取1,2,3中的较小者赋值给m
m=my_min(1,my_min(2,3))
若需要将函数体代码执行的结果返回给调用者,则需要用到return。return后无值或直接省略return,
则默认返回None,return的返回值无类型限制,且可以将多个返回值放到一个元组内。
**储备知识:函数返回值**
def max2(x,y):
if x > y:
# print(x)
return x
else:
# print(y)
return y
res = max2(10,20)
print(res * 12)
**注意**:函数体内可以有多个return,但是只要执行一次整个函数就会立即终止并且将其后之当做本次的结果返回
def foo():
print(‘hello1‘)
return 111
print(‘hello2‘)
return 2222
print(‘hello3‘)
return 3333
res = foo()
print(res)
**return有三种形式**
1、return 值:返回一个值
2、return 值1,值2,值3:支持返回多个值,并将所有返回值放进一个元组当中
3、没有return、return、return None:默认返回None
def foo():
# return 1,"aa",[1,2,3]
pass
res = foo()
print(res)
**函数调用的三种形式**
def foo(x,y):
return x + y
**语句形式**
foo(1,2)
**表达式**
res = foo(1,2)
res = foo(1,2) * 10
print(res)
函数的调用可以当做一个参数传给另外一个函数
res = foo(foo(1,2),3)
print(res)
函数的参数分为两大类
1、**形参**: 在函数定义阶段括号内指定的参数(变量名),称之为形式参数,简称形参
2、**实参**: 在函数调用阶段括号内指定的参数(变量值),称之为实际参数,简称实参
形参本质就是一个变量名,用来接收外部传来的值。
实参的值可以是常量、变量、表达式或三者的组合。
#1:实参是常量
res=my_min(1,2)
#2:实参是变量
a=1
b=2
res=my_min(a,b)
#3:实参是表达式
res=my_min(10*2,10*my_min(3,4))
#4:实参可以是常量、变量、表达式的任意组合
a=2
my_min(1,a,10*my_min(3,4))
foo(1,2)
**一 位置形参**:在函数定义阶段,按照从左到右的顺序依次定义的“变量名”
特点:必须被赋值,多一个不行少一个也不行
def foo(x,y):
print(x,y)
foo(1,2)
**二 默认形参**:在函数定义阶段,就已经为某个形参赋值了,该形参称之为默认形参
特点:调用阶段可以不用为其赋值
def foo(x,y=222):
print(x,y)
foo(111)
#111,222
**注意:**
1、可以混用位置形参与默认形参,但是默认形参必须放在后面
def foo(y=22,x): # 错误
pass
2、大多数情况传入的值都应该,就应该将对应的形参定义为默认形参,
对于每次传入的值都可能不一样的,就赢将其对应的形参定义为位置形参
def register(name,age,gender="male"):
print(name,age,gender)
register("小王",18)
register("小li",29)
register("jack",39)
register("lili",16,‘female‘)
**3、默认形参的值尽量定义成不可变类型**
# 例1
m = 100
def foo(x,y=m):
print(x,y)
m = 200
foo(1)
例2
m = []
def foo(x,y=m):
print(x,y)
m.append(111)
foo(1)
例3
def register(name, hobby, hobbies=[]):
hobbies.append(hobby)
print("%s 的爱好是 %s" % (name, hobbies))
def register(name, hobby, hobbies=None):
if hobbies is None:
hobbies = []
hobbies.append(hobby)
print("%s 的爱好是 %s" % (name, hobbies))
register(‘egon‘,"play")
register(‘tom‘,"read")
register(‘lili‘,"music")
**三 位置实参:**在函数调用阶段,按照从左到右的顺序依次传入的“变量值”
特点:按照顺序传值
def foo(x,y):
print(x,y)
foo(1,2)
foo(2,1)
**四 关键字实参**:在函数调用阶段,按照key=value的形式赋值
特点:可以打乱顺序,但是仍然能够为指定的形参赋值
def foo(x,y):
print(x,y)
foo(y=2,x=1)
**注意:**
可以混用位置实参与关键字实参,但是
1、关键字实参必须在后
2、不能给同一个形参重复赋值
def foo(x,y):
print(x,y)
foo(1,y=2)
foo(y=2,1)
foo(1,2,y=3)
**五:*args与**kwargs用在形参中:**汇总行为
***用在形参中**: *会将溢出的位置实参存成元组然后赋值给紧跟其后的形参名
def foo(x,*y):
print(x)
print(y)
foo(1,2,3,4,5,6,7)
foo(1)
def my_sum(*x): # x = (1,2,3)
res = 0
for i in x:
res += i
print(res)
my_sum(1,2,3)
****用在形参中**:**会将溢出的关键字实参存成字典然后赋值给紧跟其后的形参名
def foo(x,**y): # y = {‘y‘: 2, ‘z‘: 3, ‘a‘: 111, ‘b‘: 222}
print(x)
print(y)
foo(1,y=2,z=3,a=111,b=222)
**六:*与**用在实参中**:打撒
*用在实参中: *会将紧跟其后值打撒成位置实参
def foo(x,y,z):
print(x,y,z)
foo(*[111,222,333]) # 111,222,333
****用在实参中**: **后只能跟**字典**,**会将紧跟其后字典打撒成关键实参
def foo(x,y,z):
print(x,y,z)
foo(**{‘x‘:111,‘y‘:222,‘z‘:333}) # 111,222,333
原文:https://www.cnblogs.com/echoxkx/p/15113416.html