Python学习--Day 13
- 视频来源:python视频 900集
090.函数定义和调用
- 老师前面讲解的虚拟环境过了一下,了解了个大概
- pycharm编译器下的简洁按键:
按住Ctrl+Shift+F(format)帮助我们自动格式化,要使用Eclipse的快捷键设置。 - 打印函数名,返回的是函数所在的地址
声明一个函数,将它加载到特定的内存地址中,然后将函数名与地址相关联。
调用函数——找到函数并执行函数体的内容,python解释器遇到函数名加括号,即解释为调用
import random # 不使用两行的标准化了,占空间。
def randomint1():
a = random.randint(1, 5)
print(a)
print(randomint1)
# 输出:
# <function randomint1 at 0x0000018029B82EA0>
- 带参数的函数
使用Alt + Enter进行快速引入
import random
def generate_random(num): # num是形参
for i in range(num):
ran = random.randint(1,20)
print(ran)
# 此处使用Alt + Enter进行快速引入random
generate_random(4) # 4是实参
091.有参数的函数
- debug,打断点
在集成工具的前面点一下出现小红点,代表添加了断点,表示程序走到这先暂停,运行的时候选择debug不能使用run,注意界面上的几个箭头(用红色标注了),有很大的用处,具体功能看视频吧
第二个箭头(step in 步入)的含义是一步一步执行;
第三个箭头(step into my code)的含义是跳过一部分代码进行执行,可以理解为稍微宏观一点的一步。
- 多个函数参数形参,调用的时候要传多个实参。
092.函数使用
- 几个小练习,注意函数定义过程中的缩进问题。
- 找最大值的函数练习
我的答案:(之前自己学过return就用了)
from cmath import inf
def maxele(list1):
maxelement = -float(inf)
for i in list1:
if i > maxelement:
maxelement = i
return maxelement
listA = [1,2,3,4,5,6,7,89]
print(maxele(listA))
- 怎样判断数据类型
type(tuple1)=='tuple'
或type(tuple1)==“<class 'tuple'>”
都是不可以的。
type()只能得到是什么类型,但是判断是不是什么类型就不能用了。
看函数的底层代码——鼠标放在函数上,按住Ctrl;
isinstance(2, int)
——返回值是布尔类型,前面放变量,后面放类型。
093.回顾+问题
- enumerate()的用法忘记了,被迫回顾了一下。
enumerate()函数用于将一个可遍历的数据对象组合为一个索引序列,同时列出数据和下标,一般用于for循环中。
enumerate(seq[, start = 0])
s ={1,2,3,4,5}
for index, i in enumrate(s)
print(index, i)
- 问题:
列表是可变的,因此下面的列表相关的代码运行后的结果是移除了2以后的结果
字符串是不可变的,因此运行后,还是原来的内容
list1 = [1,2,3,4]
list2 = list1
list1.remove(2)
print(list2)
# [1,3,4]
s = 'abc'
s1 = s
s = 'abcd'
print(s1)
# 'abc'
094.函数之可变参数
- 可变参数:函数所需要传输数目不定的参数(不是一定要使用args,也可以使用arg,都可以,只要带关键的星就行)
代码不会报错,python底层遇到*args会默认准备一个元组容器,有参数就放到容器中,没有就不放。
def add(*args):
print(args)
add() # 输出 ()
add(1) # 输出 (1,)
add(1,2) # 输出 (1,2)
add(1,2,3) # 输出 (1,2,3)
- 使用*args进行累加求和的实战
def add(*args):
sum = 0
if len(args)>0:
for i in args:
sum += i
print(sum)
else:
print('0')
add() # 输出 0
add(1) # 输出 1
add(1,2) # 输出 3
add(1,2,3) # 输出 6
- 问题:如果开发的时候同时需要可变和不可变怎么办呢?
先放固定的类型在前面,随后放可变类型的,就类似于之前的:
a,*b = [1,3,4,5]
,我们可以发现a = 1、b = [3,4,5]
- 实战
def add(name,*args):
sum = 0
if len(args)>0:
for i in args:
sum += i
print(name,sum)
else:
print(name,'0')
add('name') # 输出 name 0
add('name',1) # 输出 name 1
add('name',1,2) # 输出 name 3
add('name',1,2,3) # 输出 name 6
095.关键字参数和默认值参数
- 关键字参数:key = value (最好理解成有关键字的默认值,虽然是关键字的格式,但是实际上充当的是默认的功能)
def 函数名 (参数, 关键字参数)
——关键字参数类似于默认的选择
def add (a,b = 10):
result = a + b
print(result)
add(5) # 返回15
add(2,3) # 返回5
- 多个关键字参数
传参的时候指明哪个参数(关键字)为多少,可以实现指定赋值而其他关键字不受影响
def add1(a, b = 1, c = 12):
print(a,b,c)
result = a + b + c
print(result)
add(1)
add(1,5) # 如此这般是将b赋值为5
# 如果想将c赋值为5怎么办?
add(2,c=6) # 明确指明赋值c为6
- 实战:
打印每位同学的年龄和姓名
students = {'001':('张三',12),'002':('李四', 14),'003':('王五', 15)}
def print_boy(persons):
if isinstance(persons,dict):
for name,ages in persons.values():
print(name,ages)
print_boy(students)
- 关键字参数
符号是**
,凡是前面加上两个**
的都是字典形式的关键字参数。
python底层遇到**
的时候,会自动认为要接收字典类型的格式数据,便提前准备好了字典进行数据接收。调用的时候传输实际参数,必须是A=x之类的格式,不能传输一个整体为字典格式的数据。
def func(**kwargs): # keyword argument
print(kwargs)
func(a=1,b=2,c=3)
- 拓展
在字典数据变量名前面加上**
,会使得字典数据被拆包,因此直接传输字典的数据格式是不被支持的,而可以在前面加上**
,拆包后形成的是关键字参数。
dict1 = {'001':'python','002':'java','003':'C语言'}
def func(**kwargs):
print(kwargs)
func(dict1) # 会报错,是无效的数据传输
func(**dict1) # 传递实参:给函数赋值的时候前面加上**,会将字典中的元素拆包
096.可变参数和关键字参数
- 总结:
使用的时候,如果定义的函数里面出现了**
,那么在传值的时候也要将对应的数据进行拆包和装包操作。
想把字典类型的数据传输给函数,要使用**kwargs
:
def aa(**kwargs):
print(kwargs)
aa(a='1',b='2',c='e') # 第一种方式,直接传输
dict1 = {'a'='1','b'='2','c'='e'}
aa(**dict1) # 第二种方式,加上两个**转成它可以接收的形式
- 扩展:
def vv(a,b,*c,**b)
调用这样的函数要传输什么值?传值的划分是怎样的?
分析思路:首先看传输数据中有没有关键字类型,A=x形式的,有即与**
有关。
其他的a、b是必有的变量,其余值为c的。
def vv(a,b,*c,**b):
pass
# 调用这样的函数要传输什么值?
bb(1,2) # 1 2 () {}
bb(1,2,3,4) # 1 2 (3,4) {}
bb(1,2,x=100,y=200) # 1 2 () {'x':100,'y':200}
bb(1,2,x=100,5,6) # 不符合标准,会报错。
097.可变参数之列表拆装+总结
- 引申: 见如下代码及备注。注意,将元组或列表整体传入*args,会被当作一个整体。
def func(a,*args,**kwargs):
print(a,args,kwargs)
t = (1,2,3,4)
func(1,t)
# 输出结果:
# 1 ((1,2,3,4),) {}
l = [2,5,8]
func(1,l,c=9,b=6)
# 输出结果:
# 1 ([2,5,8],) {'c':9,'b':6}
- 如果想将元组的形式放进上述代码列中,怎么办呢?类似字典的拆包和解包,
在调用函数的时候,列表或元组名称前面加上*就可以了。
def func(a,*args,**kwargs):
print(a,args,kwargs)
t = (1,2,3,4)
func(1,*t) # 加一个*
# 结果:1 (1, 2, 3, 4) {}
l = [2,5,8]
func(1,*l,c=9,b=6)
# 输出结果:
# 1 (2, 5, 8) {'c': 9, 'b': 6}
-
参数总结:
-
无参数:
def func()
——func()
即调用 -
有普通参数:
def(name,age)
——func('Amy',19)
即调用 -
可变参数(传非关键字参数):
def func(*args):
——func(...)
即调用(包括特殊的*list
、*tuple
等) -
可变参数(传关键字参数):
def func(**kwargs):
——func(...)
即调用(包括特殊的dict
) -
参数的混用,
def func(a,*args,**kwargs)
注意数据的划分 -
有默认值的关键字参数:
def add1(a, b = 1, c = 12)
——func(a[,b,c])
即调用。
098.函数之返回值
- 返回值就是return,通过return将计算运行结果扔出来。
- 有过一些基础,理解起来比较容易,就是方便将结果传给其他函数或代码块。
- 能不能一下子返回两个值?三个值?
可以,return的两个返回值会被默认放到元组中。
def add(a,b):
return a+b, 109, 34
x = add(5,6)
print(x)
# 返回结果:(11, 109, 34)
- return返回值
1.return
后面可以是一个参数,接收的时候x= func(1,2)
2.return后面也可以是多个参数,如果是多个参数则底层会将多个参数先放在一个元组中,将元组作为整体返回。
3.接收的时候也可以是多个:return 'hello','world'
,x,y = ('hello','world')
def add(a, b):
return a + b, 109, 34
x,y,z = add(5, 6)
print(x,y,z)
# 输出结果:
# 11 109 34
099.购物车添加和函数嵌套调用
- 相当于一个练习,将前面的很多知识串起来。
- 一个函数内部可以调用另一个函数。
global 变量名
——全局变量(后面还会再讲)