⑥可变长参数(2种)
1.位置可变长参数 *args 函数里面(元组)
2.关键字可变长参数 ** args 函数里面得到的是{字典}
*names-位置可变长参数 :在函数内部的表现形式:names是一个元组
def get_name(firstname,*names): print(firstname) print(names) return firstname print(get_name('lemon')) #调用函数时,可变长参数没有传入参数,就是一个空元组 #lemon () lemon
1.可以接收从函数调用的时候,多余的位置参数
def get_name(firstname,*names): print(firstname) print(names) return firstname print(get_name('lemon','python','good')) #多余的位置参数,被*names全部接收 """ lemon ('python', 'good') lemon """
2.*name必须加在其他的位置参数的后面---------位置参数是大佬(否则会报错)
一般写成*args,但是不是一定要写成*args,只是个占坑的,可以随便换可变长参数的名字,只要有意义就行。
3.可不可以只有一个可变长参数?当然可以,调用函数时传入的参数全部被*names接收
#只有一个可变长参数 def get_name(*names): return names print(get_name('lemon','python','good')) """ ('lemon', 'python', 'good') """
4.可不可以有多个可变长参数?不可以!没有必要,有一个就可以收走全部剩余的位置参数了
**kwargs--关键字可变长参数(keyword argument)
1.调用函数时**kwargs不传入参数,返回的是空字典{}
#调用函数不传入关键字参数 def get_name(*names,**kwargs): '''获取名字''' print(names) print(kwargs) print(get_name('lemon','python','good')) """ ('lemon', 'python', 'good') {} None """
2.调用函数时**kwargs传入参数,返回的是字典{},以key-value形式存储
#调用函数传入关键字参数 def get_name(*names,**kwargs): '''获取名字''' print(names) print(kwargs) print(get_name('lemon','python',teacher = 'yuz',age = '19')) """ ('lemon', 'python') {'teacher': 'yuz', 'age': '19'} None """
3.位置可变长参数*names 要放在关键字可变长参数**kwargs的前面
函数之间的调用
先举个例子,内嵌函数的调用
def eat(name,food): print('{}喜欢吃的食物:{}'.format(name,food)) def congratulate(offer_name,money): '''庆祝拿到offer''' print('{}拿到了{}元的offer'.format(offer_name,money)) eat(offer_name,'小龙虾') congratulate('李同学',20) ''' 李同学拿到了20元的offer 李同学喜欢吃的食物:小龙虾 '''
#改变eat()函数的顺序 def congratulate(offer_name,money): '''庆祝拿到offer''' print('{}拿到了{}元的offer'.format(offer_name,money)) eat(offer_name,'小龙虾')
def eat(name,food): print('{}喜欢吃的食物:{}'.format(name,food)) congratulate('李同学',20) ''' 李同学拿到了20元的offer 李同学喜欢吃的食物:小龙虾 '''
把eat()函数放在调用的后面再看看(报错,必须在调用的前面,否则找不到eat()函数,无法继续内嵌调用)
代码执行到congratulate('李同学',20)时,会跳到def congratulate(offer_name,money):函数体里面去执行,不会再去后面运行eat()函数,就是找不到eat()函数
def congratulate(offer_name,money): '''庆祝拿到offer''' print('{}拿到了{}元的offer'.format(offer_name,money)) eat(offer_name,'小龙虾') congratulate('李同学',20) #eat()函数放在congratulate()调用的后面 def eat(name,food): print('{}喜欢吃的食物:{}'.format(name,food)) ''' 李同学拿到了20元的offer NameError: name 'eat' is not defined '''
函数的作用域
1.函数的全局变量:整个文件都可以共用的,在函数体外面的
函数的局部变量:在函数体这个局部里面
话不多说,上个例子,明白易懂
def add(a,b): c = a + b print('函数里面的c'.format(c)) return c c = 4 print('函数外面的c'.format(c)) add(5,8) ''' 函数外面的c 函数里面的c ''' #先执行的是print('函数外面的c'.format(c)),再执行函数add()的调用
2.规律:全局能获取局部变量吗?--------不能!!
局部作用域能获取全局变量吗?--------能!!
全局能修改局部变量吗?-------不能!!!(全局不能获取局部变量,更不可能修改)
局部作用域能修改全局变量吗?------能(前提是加global)
全部变量、局部变量的坑(容易出面试题)
1.全局作用域不能获取局部变量
defadd(a,b): c = a + b c += 5 return c c = 4 add(5,8) print(c)#这里打印的是全部变量c,跟局部变量没有关系 ''' 4 '''
def add(a,b): c = a + b c += 5 return c c = 4 c = add(5,8) #调用函数的结果给了全部变量c,c发生了变化 print(c) ''' 18 '''
2.局部作用域能获取全局变量
c = 8 def add(a,b): return a+b+c print(add(2,4)) ''' 14 '''
3.加global,在局部作用域修改全局变量
❤不加global 表明是全局变量,局部是不能修改全局变量的
如果想在局部去修改全局变量,加global 表明这是一个全局变量
c = 4 def add(a,b): c = c + 4 # '='号前面的c是局部作用域的变量,'='号后面的c是全局变量,到底是局部变量还是全局变量,就搞不清楚了
print(c) return a+b+c add(2,4) #报错!!局部不能修改全局变量(在没有global关键字的时候)
#在局部作用域加global,将局部的c变成全局 c = 4 def add(a,b): global c c = c + 4 print(c) add(2,4) print('最后的c是{}'.format(c)) ''' 8 最后的c是8 '''
总结:位置参数、默认参数、关键字参数混合在一起
1.位置参数一定是排在前面,默认参数、关键字参数放在后面(也就是没有=号的在前面,有=号的必须放在后面),否则就是错的。
2.函数的调用禁忌!!!!
①2个函数不要去相互调用,相互调用会导致递归错误,内存有限,一直循环,内存会爆掉。(recursionError:递归错误)
def get_money(date): get_name('pig','li') return '我再{}号讨薪资'.format(date) def get_name(firstname,lastname): get_money(9) return firstname + lastname print(get_money(9))
②函数不要自己调用自己,否则也会导致递归错误
def get_money(date): print('去讨薪') get_money(date) print(get_money(8))#死循环
为什么要使用函数(函数的作用)-------存储一段代码、程序
1、当你发现你在复制、粘贴相同的或者类似的代码的时候,那么,极有可能你需要定义一个函数,会把同样的一段代码存储到函数当中-----→封装
封装成函数:把一段代码存储在函数中
封装成函数,重复利用一段代码的时候,只需要重复调用一个函数就可以了。
2.函数可不可以存储变量?不存储(变量一般是放在函数的外面),函数里面的是一个形式参数
实际参数被这样提取出来:如果想把一段代码封装成函数,里面有变量的值一直是变化的,就可以这个变量作为形式参数,放在函数里面。(函数一般是有参数的,也可以在参数里面用input动态的获取参数)
内置函数(69个)
①abs() 返回一个数的绝对值
②set() 集合的转化函数 去重
③dict() 字典的转化函数
④list() 列表的转化函数
⑤max() 返回最大值的函数
⑥min() 返回最小值的函数
⑦sorted()对一个可迭代对象的排序(从小到大)
❤sort() 与sorted()对比------面试题
1.使用时表示不一样list1.sort() sorted(list1)
2.是否修改原列表
sorted()返回的是一个新的列表,----sorted()有返回值,是个新的列表,原列表没有变化
lst = [1,4,7,2,9,8] print(sorted(lst)) print(lst) ''' [1, 2, 4, 7, 8, 9] [1, 4, 7, 2, 9, 8] '''
sort()----没有返回值,只是修改了原列表
lst = [1,4,7,2,9,8]
new_lst = lst.sort()
print(new_lst)#sort()函数没有返回值
print(lst)
'''
None
[1, 2, 4, 7, 8, 9]
'''
⑧enumerate() 枚举 可以同时获取 索引,和对应的值,元组形式
lst = [1,5,3,7,8,2] for i in enumerate(lst): print(i) ''' (0, 1) (1, 5) (2, 3) (3, 7) (4, 8) (5, 2) '''
lst = [1,5,3,7,8,2] for i,v in enumerate(lst): #两个值就是元组的解包 print(i,v) ''' 0 1 1 5 2 3 3 7 4 8 5 2 '''
⑨input() 控制台输入函数
⑩ bool() 布尔类型转化
11.eval() 执行一个字符串表达式,并返回表达式的值。---若果有字符串里面有数据运算,可以使用eval()
a = '1 + 2' print(a) print(eval(a)) ''' 1 + 2 3 '''
12.open() 打开文件 与close()函数对应使用