标签:传值 函数调用 返回值 函数定义 gif sel 部分 运算 comm
函数重点:
什么是函数? 为什么要用函数? 函数的分类:内置函数与自定义函数 如何自定义函数 语法 定义有参数函数,及有参函数的应用场景 定义无参数函数,及无参函数的应用场景 定义空函数,及空函数的应用场景 调用函数 如何调用函数 函数的返回值 函数参数的应用:形参和实参,位置参数,关键字参数,默认参数,*args,**kwargs 高阶函数(函数对象) 函数嵌套 作用域与名称空间 装饰器 迭代器与生成器及协程函数 三元运算,列表解析、生成器表达式 函数的递归调用 内置函数 面向过程编程与函数式编程
一、用函数与不使用函数的问题(具备某一功能的工具即函数)
1、组织结构不清晰
2、代码冗余
3、无法统一管理且维护难度大
二、函数分类
1、内置函数
2、自定义函数
1、内置函数:python 解释器自带的函数,python解释器启动就会定义好这些函数
2、自定义函数:
语法:
def 函数名(参数1,参数2,...):
‘‘‘注释信息‘‘‘
函数体
return 返回值
三、为何要定义函数
函数即变量,变量必须先定义后使用,未定义而直接引用函数,就相当于引用一个不存在的变量名。
四、定义函数做的事?
只检测语法,不执行代码。
五、如何定义函数(函数名要反映其意义)
def...
六、定义函数的三种形式
无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印
有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值
空函数:设计代码结构
七、函数的调用(函数:必须遵循先定义,后调用)
1 先找到名字
2 根据名字调用代码
def tell_tag():#定义阶段 print(‘======‘) def tell_msg(msg): print(msg) #调用阶段 # tell_tag() # tell_msg(‘hello world‘) # tell_tag()
函数的返回值?
0->None
1->返回1个值
多个->元组
什么时候该有?
调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
什么时候不需要有?
调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
通常无参函数不需要有返回值
八、函数调用的三种形式
1、语句形式:foo()
2、表达式形式:3*len(‘hello’)
3、当中另外一个函数的参数:range(len(‘hello‘))
九、函数的参数
1 形参和实参定义
2 形参即变量名,实参即变量值,函数调用则将值绑定到名字上,函数调用结束,解除绑定
3 具体应用
位置参数:按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
关键字参数:按照key=value的形式定义实参
无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右面
2. 对同一个形参不能重复传值
默认参数:形参在定义时就已经为其赋值
可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
可变长参数:
针对实参在定义时长度不固定的情况,应该从形参的角度找到可以接收可变长实参的方案,这就是可变长参数(形参)
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参也应该有两种解决方案,分别是*args,**kwargs
===========*args===========
def foo(x,y,*args):
print(x,y)
print(args)
foo(1,2,3,4,5)
def foo(x,y,*args):
print(x,y)
print(args)
foo(1,2,*[3,4,5])
def foo(x,y,z):
print(x,y,z)
foo(*[1,2,3])
===========**kwargs===========
def foo(x,y,**kwargs):
print(x,y)
print(kwargs)
foo(1,y=2,a=1,b=2,c=3)
def foo(x,y,**kwargs):
print(x,y)
print(kwargs)
foo(1,y=2,**{‘a‘:1,‘b‘:2,‘c‘:3})
def foo(x,y,z):
print(x,y,z)
foo(**{‘z‘:1,‘x‘:2,‘y‘:3})
===========*args+**kwargs===========
def foo(x,y):
print(x,y)
def wrapper(*args,**kwargs):
print(‘====>‘)
foo(*args,**kwargs)
命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
可以保证,传入的参数中一定包含某些关键字
def foo(x,y,*args,a=1,b,**kwargs):
print(x,y)
print(args)
print(a)
print(b)
print(kwargs)
foo(1,2,3,4,5,b=3,c=4,d=5)
结果:
1
2
(3, 4, 5)
1
3
{‘c‘: 4, ‘d‘: 5}
#1、形参与实参
#形参:在函数定义阶段,括号内定义的参数的称为形参,相当于变量名
#实参:在函数调用阶段,括号内定义的参数的称为实参,相当于变量值
#在调用阶段,实参的值会绑定给形参,调用结束后解除绑定关系
# def foo(x,y):
# print(x,y)
# foo(1,2)
#参数的分类:
‘‘‘
1、位置参数
位置形参:必选被传值的参数,多一个不行,少一个不行
位置实参:从左到右依次赋值给形参
‘‘‘
# def foo(x,y):
# print(x,y)
# foo(1,2)
‘‘‘
#2、关键字参数:在函数调用阶段,按照key=value的形式定义实参
可以不依赖位置,指名道姓给形参传值
注意:可以与位置形参混用:
1、位置实参必须在关键字实参的前面
2、不能为一个形参重复传值
‘‘‘
# def foo(x,y):
# print(x,y)
# foo(1,y=2)#
‘‘‘
#3、默认参数:在函数的定义阶段,已经为形参赋值了,在定义阶段已经赋值,意味着在调用阶段可以不传值
经常变得用形参,不变的用实参。
注意:
1、默认参数的值,只在定义时赋值一次
2、位置形参应在默认参数的前面
3、默认参数的值应是不可变类型
‘‘‘
# def foo(x,y=10):
# print(x,y)
# foo(x=8,y=11)
# def register(name,age,sex=‘male‘):
# register(‘egon‘,18)
# register(‘alex‘,38,None)
# def register(name,age,sex=‘boy‘):
# print(name,age,sex)
# register(‘chy‘,18)
‘‘‘
4、可变长参数
实参可变长度:实参值的个数是不固定的
而实参的定义形式两种:
1、位置实参 *
2、关键字实参 **
针对这两种形式的实参个数不固定,相应的,形参也有两种解决方案
‘‘‘
# #针对按照位置定义
# def func(x,y,*args):
# print(x,y)
# print(args)
# func(1,2,3,4)
# func(1,2,*[3,4])#func(1,2,3,4)
# func(*[1,2,3,4])
# func(1,2)#()为空
#
# def fun(x,y,z):
# print(x,y,z)
# l=[1,2,3]
# fun(*l)
#针对按照关键字定义的那部分实参,形参:**kwargs
# def foo(x,y,**kwargs):
# print(x,y)
# print(kwargs)
# foo(y=2,x=1,z=3,b=2)
# foo(1,2,3,y=2,x=1,z=3,b=2)
# foo(y=1,x=2,**{‘a‘:1,‘b‘:2,‘c‘:3})#无序
# 用途:装饰器
#5、命名关键字参数:形参中,在*后定义的参数称之为命名关键字参数
#特性是:传值时必须按照关键字实参的形式传值
def foo(x,y,*args,a=1,b):
print(args)
print(x,y,a,b)
foo(1,2,6,7,b=3,a=4)
#形参:位置参数===》默认参数===》*args===》命名关键字惨呼===》**kwargs
十、阶段性练习
一、函数对象
函数是第一类对象,即函数可以当作数据传递
1、可以被引用
2、可以当作参数传递
3、返回值可以是函数
4、可以当做容器类型的元素
#利用该特性,优雅的取代多分支的if
def foo():
print(‘foo‘)
def bar():
print(‘bar‘)
dic={
‘foo‘:foo,
‘bar‘:bar,
}
while True:
choice=input(‘>>: ‘).strip()
if choice in dic:
dic[choice]()
#1、函数是第一类对象:函数可以当做数据来使用 def foo(): print(‘from foo‘) #可以被引用 # f=foo # print(f) #可以当做参数传入一个函数 # def foo(m): # print(m) # foo(x) # def wrapper(func): # print(func) # func() # wrapper(foo) #可以当做函数的返回值 # def bar(): # return x # print(bar()) # def wrapper(): # return foo # f=wrapper() # print(f is foo) #可以当做容器类型的一个元素 # print([x,1,2]) # l=[foo,1,2] # l[0]() def select(sql): print(‘select功能:‘,sql) def update(sql): print(‘update功能:‘,sql) def insert(sql): print(‘insert功能:‘,sql) def delete(sql): print(‘delete功能:‘,sql) func_dic={ ‘select‘:select, ‘update‘:update, ‘insert‘:insert, ‘delete‘:delete, } def main(): while True: inp=input(‘>>: ‘).strip() if not inp:continue sql=inp.split() cmd=sql[0] if cmd in func_dic: func_dic[cmd](sql) else: print(‘command not found‘) main()
二、函数的嵌套
1、函数的嵌套调用 def max(x,y): return x if x > y else y def max4(a,b,c,d): res1=max(a,b) res2=max(res1,c) res3=max(res2,d)
return res3
print(max4(1,2,3,4))
2、函数的嵌套定义:在定义一个函数内部,又定义了一个函数
三、名称空间与作用域
1、名称空间:存放名称与值绑定关系的地方
内置名称空间:内置的名字与值的绑定关系
生效:python解释器启动后
失效:python解释器关闭后
全局名称空间:文件级别定义的名字与绑定关系
生效:执行python文件时,将改文件级别定义的名字与绑定关系生效
失效:文件执行完毕
局部名称空间:函数内部定义的名字与值的关系
生效:调用函数临时失效
失效:函数调用结束
加载顺序:内置==》全局==》局部(不一定会产生)
查找名字的顺序:局部=全局==》内置=》
2、作用域
全局作用域:包含内置空间的名字与全局空间的名字
全局存活、全局有效(伴随着程序的开始到结束)
局部作用域:包含局部名称空间的名字
临时存活、局部有效(临时存活)
# print(globals())
# print(locals())
‘‘‘
作用域关系:在函数定义时,就已经固定了,与调用位置无关
‘‘‘
x=10000000000000000000000
def f1():
def f2():
print(x)
return f2
f=f1()
print(f)
#global nonlocal #硬改全局
x=1
def f1():
global x
x=10
f1()
print(x)
def func():
# x=123 除了全局那改,其它的没有意义
f()
func()
#nonlocal 从函数内部找,硬改全局
x=155
def f1():
x=26
def f2():
nonlocal x
x=1111
f2()
f1()
print(x)
标签:传值 函数调用 返回值 函数定义 gif sel 部分 运算 comm
原文地址:http://www.cnblogs.com/chyc/p/7533411.html