今天学习内容有函数的返回值、函数参数的使用、名称空间与作用域、函数嵌套。
下来我们一一查看。
函数的返回值
看几个栗子:
def func(x): return x**2 y=func(10) print(y)
def foo(): return None res=foo() print(res)
def foo(): return{‘a‘:1} res=foo() print(res[‘a‘])
def foo(): return {‘a‘:1},1,‘a‘,[1,2] res=foo() print(res) 结果:({‘a‘: 1}, 1, ‘a‘, [1, 2])
def foo(): return 1 print(‘======>‘) return 2 return 3 return 4 print(foo())结果:1
下面我们来总结一下返回值的效果:
‘‘‘
返回值:可以返回任意类型
没有return:默认返回None
return value: value
return val1,val2,val3 :(val1,val2,val3) 返回元祖类型
return的效果:只能返回一次值,终止函数的执行
‘‘‘
函数参数的使用
def foo(x): print(x) foo(1) foo(‘a‘) foo({‘a‘:2})结果:1a{‘a‘: 2}
#形参与实参: def foo(x,y): return x+y print(foo(1,2))结果:3
位置参数:按照从左到右的顺序依次定义的参数
- 按位置定义的形参,必须被传值,多一个不行,少一个也不行
- 按位置定义的实参,与形参一一对应
关键字参数:实参在定义时,按照key=value形式定义
- #关键字参数可以不用像位置实参一样与形参一一对应,指名道姓地传值
def foo(x,y): print(x) print(y) foo(y=1,x=10) 结果: 10 1
def foo(x,y,z): print(x) print(y) print(z) foo(1,y=2,z=10) 结果: 1 2 10
- 注意的问题一:位置实参必须在关键字实参的前面
- 注意的问题二:实参的形式既可以用位置实参又可以是关键字实参,但是一个形参不能重复传值
默认参数:在定义函数阶段,就已经为形参赋值,定义阶段有值,调用阶段可以不用传值
def func(x,y=10): print(x) print(y) func(1,20) func(1) 结果: 1 20 1 10
- 默认参数需要注意的问题一:必须放在位置形参后面
- 默认参数需要注意的问题二:默认参数通常要定义成不可变类型
- 默认参数需要注意的问题三:默认参数只在定义阶段被赋值一次
形参的应用:值经常变化的需要定义成位置形参
值大多数情况下都一样,需要定义成默认参数
可变长参数:可变长指的是实参的个数不固定
- 按位置定义的可变长度的实参:*
- 按关键字定义的可变长度的实参:**
def func(x,y,*args): #x=1,y=2,args=(3,4,5,6) print(x,y) print(args) func(1,2,3,4,5,6) 结果: 1 2 (3, 4, 5, 6)
def func(x,y,*args): #args=(3,4,5,6) print(x,y) print(args) func(1,2,*(3,4,5,6)) #foo(1,2,3,4,5,6) 结果: 1 2 (3, 4, 5, 6)
def func(x,y,**kwargs): #x=1,y=2,kwargs={‘a‘:1,‘b‘:3,‘z‘:3} print(x,y) print(kwargs) func(1,y=2,z=3,a=1,b=3) 结果: 1 2 {‘z‘: 3, ‘a‘: 1, ‘b‘: 3}
def func(x,y=1,z=1): print(x,y,z) func(**{‘y‘:2,‘x‘:1,‘z‘:3}) 结果: 1 2 3
def wrapper(*args,**kwargs): #可以接受任意形式,任意长度的参数 print(args) print(kwargs) wrapper(1,2,3,3,3,3,3,x=1,y=2,z=3)
命名关键字参数:定义在*后的形参,这类形参,必须被传值,而且要求实参必须是以关键字的形式来传值
def register(name,age,*,group,**kwargs): print(name) print(age) print(kwargs) print(group) register(‘egon‘,18,group=‘group1‘,hobby=‘play‘) 结果: egon 18 {‘hobby‘: ‘play‘} group1
def register(**kwargs): print(kwargs) if ‘name‘ in kwargs: print(kwargs[‘name‘]) if ‘age‘ in kwargs: print(kwargs[‘age‘]) register(name=‘egon‘,age=18) register() 结果: {‘name‘: ‘egon‘, ‘age‘: 18} egon 18 {}
def register(*args,name=‘egon‘,age): print(args) print(name) print(age) register(name=‘alex‘,age=18) register(1,2,3,3,age=10) 结果: () alex 18 (1, 2, 3, 3) egon 10
引用形参顺序:位置形参,默认参数,*args,命名关键字参数,**kwargs
名称空间与作用域
名称空间:存放名字与值的绑定关系
名称空间分为三种:
- 内置名称空间:python解释器自带的名字,python解释器启动就会生成
- 全局名称空间:文件级别定义的名字都会存放与全局名称空间,执行python文件时会产生
x=1def func(): pass class Foo: pass import os if 1 > 2 : y=3
- 局部名称空间:定义在函数内部的名字,局部名称空间只有在调用函数时才会生效,函数调用结束则失效
三者的加载顺序:内置名称空间->全局名称空间->局部名称空间
取值:局部名称空间->全局名称空间->内置名称空间
max=10 def func(): max=20 print(max) func() 结果: 20
max=10def func(): # max=20 print(max) func() 结果:10
x=0 def f1(): x=1 def f2(): x=2 def f3(): x=3 print(x) f3() f2() f1() 结果: 3
作用域:作用范围
全局作用域:内置名称空间与全局名称空间的名字属于全局范围,在整个文件的任意位置都能被引用,全局有效
局部作用域:局部名称空间的名字属于局部范围,只在函数内部可以被引用,局部有效
x=1 def foo(): def f2(): print(x) f2() def bar(): print(x) foo() bar() 结果: 1 1
def f1(): x=1 def f2(): x=2 print(x) f2() f1() 结果: 2
函数嵌套
函数的嵌套调用
def max2(x,y): if x > y: return x else: return y def max4(a,b,c,d): res1=max2(a,b) res2=max2(res1,c) res3=max2(res2,d) return res3 print(max4(11,23,-7,31)) 结果: 31
函数的嵌套定义
def f1(): def f2(): def f3(): print(‘from f3‘) print(‘from f2‘) f3() print(‘from f1‘) f2() # print(f1) f1() 结果: from f1 from f2 from f3
函数对象
函数是第一类对象: 指的是函数可以被当做数据传递
def func(): print(‘from func‘) #可被引用 # f=func
#可以当做函数的参数
def func(): print(‘from func‘) def foo(x): print(x) x() foo(func) 结果: C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe C:/Users/Administrator/PycharmProjects/untitled/课堂练习.py <function func at 0x00000000005D3E18> from func Process finished with exit code 0
#可以当做函数的返回值
def foo(): print(‘from foo‘) def bar(): return foo f=bar() print(f) print(foo) 结果: C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe C:/Users/Administrator/PycharmProjects/untitled/课堂练习.py <function foo at 0x0000000001D73E18> <function foo at 0x0000000001D73E18> Process finished with exit code 0
x=0 def f1(): x=1 def f2(): # x=2 print(x) return f2 f=f1() # print(f) f() 结果: 1
#可以当做容器类型的元素
def select(): print(‘select function‘) func_dic={ ‘select‘:select, } # print(func_dic[‘select‘]) func_dic[‘select‘]() 结果: select function
def select(): print(‘select func‘) def delete(): print(‘delete func‘) def change(): print(‘change func‘) def add(): print(‘add func‘) while 1: cmd=input(‘>>: ‘).strip() if not cmd: continue if cmd == ‘select‘: select() elif cmd == ‘delete‘: delete() elif cmd == ‘change‘: change() elif cmd == ‘add‘: add() else: print(‘无效的命令‘)
def select(cmd_l):
filename=cmd_l[-1]
pattern=cmd_l[1]
with open(filename,‘r‘,encoding=‘utf-8‘) as f:
for line in f:
if pattern in line:
print(line)
def delete():
print(‘delete func‘)
def change():
print(‘change func‘)
def add():
print(‘add func‘)
def check():
print(‘check func‘)
func_dic={
‘select‘:select,
‘delete‘:delete,
‘change‘:change,
‘add‘:add,
‘check‘:check,
}
while 1:
inp=input(‘>>: ‘).strip()
if not inp:continue
cmd_l=inp.split()
# print(cmd_l)
cmd=cmd_l[0]
if cmd in func_dic:
func_dic[cmd](cmd_l)
else:
print(‘无效的命令‘)