一、编程第一步,函数来引入
学到这一步,我们已经使用过大量函数,如len()、max()、print()等,使用函数是真正开始编程的第一步。
比如在程序中定义了一段代码用于实现一个特定的功能。问题来了:如果下次还需要实现同样的功能,难道要把前面的代码复制一次?很明显,这种方法很笨拙,若是每次都复制会出现大量的代码冗余终归不是好的解决之道。所以我们引入了函数的概念:对代码块和功能的封装和定义。通俗的来讲,所谓函数就是指为一段实现特定功能的代码取一个名字,以后即可通过该名字来执行(调用)该函数即可。请看以下代码:
def xiu():
print("我自青衫白马客,")
print("踏驹举酒醉山河。")
print("笔锋三两疏狂意,")
print("拔剑星辰落几颗?")
xiu()
xiu()
运行结果:
二、 函数的定义, 函数名, 函数体以及函数的调用
我们使⽤def关键字来定义函数, 函数的定义语法:
def 函数名():
函数体
函数调用
这⾥的函数名的命名规则和使⽤和变量基本⼀样,可以⾃⼰回顾⼀下变量的命名规则。
**函数体: ** 就是函数被执行之后要执行的代码。
函数的调用: 使⽤函数名可以调⽤函数, 写法: 函数名(), 这个时候函数的函数体会被执⾏。
程序执行过程分析:
1.定义函数xiu()
2.调用函数xiu()
3.调用函数xiu()
4.开始执行函数xiu()
5.执行函数体
6.xiu()这次调用完毕
7.函数执行完毕,xiu()本次调用完毕
如果还想再重复函数体, 多次调⽤就可以了,很⽅便。
三、函数的返回
执⾏完函数之后我们可以使⽤return来返回结果.
函数中return的使⽤:
1. 函数中遇到return, 此函数结束, 不再继续执⾏:
def xiu():
print("我自青衫白马客,")
print("踏驹举酒醉山河。")
print("笔锋三两疏狂意,")
return
print("拔剑星辰落几颗?") #这句话不会被执行
xiu()
结果:
2. 给函数的调用者⼀个访问结果
def xiu():
print("我自青衫白马客,")
print("踏驹举酒醉山河。")
print("笔锋三两疏狂意,")
print("下一句是:")
return"拔剑星辰落几颗?" #如果什么都不写,下面的print返回None
shi = xiu()
print(shi) #拔剑星辰落几颗?
结果:
函数的返回值可以有多个结果:
def xiu():
print("我自青衫白马客,")
print("踏驹举酒醉山河。")
print("笔锋三两疏狂意,")
print("下一句是:")
return"拔剑星辰落几颗?","相思渐觉诗狂少"
shi = xiu()
print(shi)
print(type(shi))
结果:
总结⼀下:
1. 遇到return. 此函数结束, 函数后⾯的东⻄将不会再执行
2. return 返回值
关于返回值:
如果return什么都不写 或者干脆不写return .那么返回的就是None
如果return后⾯写了⼀个值. 则调用者可以接收⼀个结果
如果return后⾯写了多个结果, 则调用者可以接收⼀个tuple, 调用者可以直接解构成
多个变量
四. 函数的参数
参数, 函数在调⽤的时候指定具体的⼀个变量的值就是参数。语法:
def 函数名(参数列表):
函数体
def yue(chat):
print("拿出⼿机")
print("打开"+chat)
print("找个好友")
print("约不约?")
yue("微信")
yue("QQ")
我们在调⽤函数yue的时候给chat⼀个值,然后再执⾏函数体可得到如下结果:
**关于参数: **
1. 形参
写在函数声明的位置的变量叫形参,形式上的⼀个完整. 表⽰这个函数需要xxx
2. 实参
在函数调⽤的时候给函数传递的值. 叫实参, 实际执⾏的时候给函数传递的信息. 表⽰给函数
xxx
3. 传参
给函数传递信息的时候将实际参数交给形式参数的过程被称为传参。
关于实参
1.位置参数
在传参过程中,如果有多个实参,系统会默认按照位置把实参赋值到形参。
练习: 编写函数, 给函数传递两个参数a, b. 比较a, b的⼤⼩, 返回 a, b中最⼤的那个数。
代码示例:
# 1.传统方法
def da(a,b):
if a>b:
print(a)
else:
print(b)
da(3,8)# 3,8即为实参里的位置参数
# 2.return
def da(a,b):
if a>b:
return a
else:
return b
s = da(3,8)
print(s)
# 3.三目运算
def da(a, b):
c = a if a > b else b # 当a>b成⽴返回a, 否则返回b
return c
print(da(3,8))
结果:
2.关键字参数
位置参数好不好呢? 如果是少量的参数还算OK, 没有问题. 但是如果函数在定义的时候参
数非常多怎么办? 程序员必须记住, 我有哪些参数, 而且还要记住每个参数的位置, 否则函数
就不能正常调⽤了. 那则么办呢? python提出了⼀种叫做关键字参数. 我们不需要记住每个参
数的位置. 只要记住每个参数的名字就可以了,代码示例:
def yue(chat, address, age):
print("拿出⼿机")
print("打开"+chat)
print("找个"+address+"附近漂亮的"+str(age)+"岁妹⼦")
print("约不约")
yue(chat="脸书", age=18, address="华盛顿") # 关键字参数
结果:
3 混合参数
可以把上⾯两种参数混合着使⽤. 也就是说在调⽤函数的时候即可以给出位置参数, 也可
以指定关键字参数.
# 混合参数
yue("脸书", age=18, address="华盛顿") # 正确.第⼀个位置赋值给chat, 后⾯的参数开始
#指定关键字.
yue(age="18", "脸书", address="纽约") # 错误, 最开始使⽤了关键字参数, 那么后⾯的
#微信的位置就串了, 容易出现混乱
敲黑板:
注意: 在使⽤混合参数的时候, 关键字参数必须在位置参数后面
小结
综上: 在实参的⾓度来看. 分为三种:
1. 位置参数
2. 关键字参数
3. 混合参数, 位置参数必须在关键字参数前面
关于形参
1.函数的缺省参数:
语法:
def 函数名(形参1=默认实参1,形参2=默认实参2,...):
语句
示例:
def info(name, age=1, address="不详"):
print("我叫:", name, ",我今年:", age, "岁,家庭地址:", address)
info("小王子", 30, "B-612小星球")
# 我叫: 小王子 ,我今年: 30 岁,家庭地址: B-612小星球
info("东方不败", 100)
# 我叫: 东方不败 ,我今年: 100 岁,家庭地址: 不详
info("鲁夫中")
#我叫: 鲁夫中 ,我今年: 1 岁,家庭地址: 不详
说明:
** 缺省参数必须自右至左依次存在
缺省参数可以有零个,一个,多个,甚至全部都有缺省参数
缺省参数的绑定对象存在于函数内,同函数的生命周期一致
**
函数的形参定义方式:
1.位置形参
2.星号元组形参
3.命名关键字形参
4.双星号形参*
1.位置形参:
def 函数名(形参1,形参2,...):
语句块
2.星号元组形参:
语法:
def 函数名(*元组形参名)
语句块
作用:
收集多余位置形参
示例:
此星号元组形参示例:
def func(*args):
print("实参个数是:", len(args))
print("args的值是:", args)
func(1, 2, 3)
func("a", 5, True, 2.89)
结果:
3.命名关键字形参:
语法:
def 函数名(*,命名关键字形参):
语句块
或
def 函数名(*args,命名关键字形参):
语句块
** 作用:**
所有的命名关键字形参都强制调用者采用关键字传参或字典关键字传参的方式传递
示例:
def myfun(a, *, k): # 有两个形参
print("a=", a)
print("k=", k)
#myfun(100, 200) # 错
myfun(100, k=200) # k 强制是用关键字传参
myfun(10, **{"k": 20})
结果:
def myfun2(b, *args, c, d):
print("b=", b)
print("args=", args)
print("c=", c)
print("d=", d)
#myfun2(100, 200, 300, 400) # 错
myfun2(100, 200, 300, 400, d=600, c=500)
结果:
3.双星号字典形参:
语法:
def 函数名(**字典形参名):
语句块
作用:
收集多余的关键字
注:
字典形参通常叫kwargs
示例:
双星号字典形参的用法:
def func(**kwargs):
print("关键字传参的个数是:", len(kwargs))
print("kwargs=", kwargs)
func(name="tarena", age=15)
func(a=1, b="BBBB", c=[2, 3, 4], d=True)
结果:
函数参数说明:
位置形参,缺省参数,双星号元组形参,命名关键字形参,双星号字典形参可以混合使用
函数参数自左至右的顺序为:
1.位置形参
2.星号元组形参
3.命名关键字形参
4.双星号字典形参
示例:
def fn(a, b, *args, c, **kwargs):
print(a, b, args, c, kwargs)
fn(100, 200, 400, *"AB", **{'d': "D"}, c=1000)
fn(100, 200, 400, *"AB", **{'d': "D", 'c': "C"}, e=1000)
结果:
可以接受任意位置传参和关键字传参的函数:
def fn(*args,**kwargs):
pass