一.什么是函数?
1 def 函数名() #函数名是字母数字下划线的任意组合,且不能数字开头 2 ''' 3 文档描述 4 ''' 5 代码块 6 return 返回值 7 函数名() 8
二.函数返回值
return 返回值
1.返回一个值(返回object)
2.返回多个值
可以用一个变量接收,组成元组,也可以多个变量接收
三.函数的参数
1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
3.位置参数
传参方式:
按照位置传参;
按照关键字传参;
位置传参和关键字传参混用,但位置参数必需在关键字传参之前
4.默认参数
注意:默认参数只在被定义时生效一次
作用:将变化比较小的值设置为默认参数
当实参是个可变数据类型时不建议使用
5.动态参数
1 def mysum(*args): 2 the_sum = 0 3 for i in args: 4 the_sum+=i 5 return the_sum 6 the_sum = mysum(1,2,3,4) 7 print(the_sum) 8 9 10 def stu_info(**kwargs): 11 print(kwargs) 12 print(kwargs['name'],kwargs['sex']) 13 stu_info(name = 'alex',sex = 'male')
6.实参*(1,2,3,4,5)表示打散:(1,2,3,4,5),类似for循环出每个元素
7.命名关键字参数
def foo(x,y,*,a=5,b,c) #*号后面,a=5 命名关键字参数 #b c 在传参数时须按照b=5,c=6这种形式传
四.全局变量与局部变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值:
在局部调用:局部命名空间->全局命名空间->内置命名空间
作用域
全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
globals()
globals() 函数会以字典类型返回当前位置的全部全局变量,包括所有导入的变量。
locales()
locals() 函数会以字典类型返回当前位置的全部局部变量。
五.函数的嵌套和作用域链
嵌套定义(例子):
1 def f1(): 2 print("in f1") 3 def f2(): 4 print("in f2") 5 6 f2() 7 f1() 8 9 10 def f1(): 11 def f2(): 12 def f3(): 13 print("in f3") 14 print("in f2") 15 f3() 16 print("in f1") 17 f2() 18 f1()
作用域链(例子):
1 def f1(): 2 a = 1 3 def f2(): 4 print(a) 5 f2() 6 f1() 7 8 9 def f1(): 10 a = 1 11 def f2(): 12 def f3(): 13 print(a) 14 f3() 15 f2() 16 f1() 17 18 19 def f1(): 20 a = 1 21 def f2(): 22 a = 2 23 f2() 24 print('a in f1 : ',a) 25 26 f1()
关键字:nonlocal
使用:
1 def f1(): 2 a = 1 3 def f2(): 4 nonlocal a 5 a = 2 6 f2() 7 print('a in f1 : ',a) 8 f1()
六.函数名的本质(内存地址)
1.可以被引用
2.可以被当容器类型的元素
3.可以当做函数的参数和返回值,简单来说就是一个变量
七.闭包
1 def func(): 2 name = 'eva' 3 def inner(): 4 print(name)
闭包函数的定义:
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
函数内部定义的函数称为内部函数
使用:
1 def func(): 2 name = 'eva' 3 def inner(): 4 print(name) 5 return inner 6 f = func() 7 f()
八.装饰器
定义:本质是一个函数,为其他函数增加新功能
遵循原则:
1.不修改被装饰函数的源代码
2.不修改被装饰函数的调用方式
框架:
1 def timer(func): 2 def inner(*args,**kwargs): 3 '''执行函数之前要做的''' 4 re = func(*args,**kwargs) 5 '''执行函数之后要做的''' 6 return re 7 return inner
执行顺序:
实例:
1 auth_status = { 2 'user:': None, 3 'status': False 4 } 5 def user_info (func): 6 def inner(*args,**kwargs): 7 if auth_status['status']: 8 ret = func(*args, **kwargs) 9 return ret 10 else: 11 user_name = input('请输入用户名:').strip() 12 password = input('请输入密码:').strip() 13 f = open('abc.text') 14 cont = f.read() 15 content = eval(cont) 16 if content.get(user_name) and password == content[user_name]: 17 print('login successful!') 18 auth_status['user'] = user_name 19 auth_status['status'] = True 20 ret = func(*args, **kwargs) 21 return ret 22 else: 23 print('login failed!') 24 return inner 25 @user_info 26 def user(a,b): 27 print('欢迎来到主页') 28 @user_info 29 def user_a(): 30 print('欢迎回家') 31 user(1,2) 32 user_a()
九.函数的应用
迭代器 和生成器
http://www.cnblogs.com/sxh-myblogs/p/7274565.html
十.补充
函数对象也被称为第一类对象有以下特点:
1.可以被引用
2.可以当作参数传给函数
3.可以当作返回值
4.可以当作容器类型元素
def asd(): print('asd') def abc(): print('abc') def xyz(): print('xyz') dic ={'asd':abc,'abc':asd,'xyz':xyz} while True: cmd = input('===>:').strip() if cmd in dic: dic[cmd]()
5. if __name__ == '__main__'
含义:
if __name__ = '__main__': suite 1 #通过__name__ = __main__判断执行程序是不是主程序,如果是主程序则执行suite 1,如果当前文件是被调用的话,这个条件就不成立了,suite 1就不会被执行。 #常用做来测试
6. 名称空间与作用域
含义:内存级别的隔离空间,即存放名字与值绑定关系的地方
1.内置的名称空间:随python解释器运行产生,解释器关闭时回收,存放自带的名字
2.全局名称空间:执行python文件产生,存放文件级别定义的名字
3.局部名称空间:只有在调用函数时临时产生,调用结束后回收,存放函数内部定义的名字
作用域:
内置空间和全局空间称谓全局作用域,文件执行时生效,执行结束失效,全局存活,全局有效
局部:包含局部名称空间名字,调用生效 ,结束失效,临时存活,局部有效
强调:作用域关系在函数定义阶段固定,与调用位置无关。
7.闭包函数:
函数体需要参数的方式
传参形式,闭包函数
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
from urllib.request import urlopen def outer(): url = 'http://www.baidu.com' def index(): return urlopen(url).read() return index() a = (outer().decode('utf-8')) print(a)
8.三元表达式:
return x if x > y else y