函数(八)-函数和匿名函数
计算机函数:subroutine 子程序,procedure 过程
语法
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体
# python 中定义函数 def test(x): "the function definitions" x += 1 return x ''' def 定义函数的关键字 test:函数名 “”:文档描述符(非必要) ''' print(test(7)) def test_02(): msg = 'test_02' print(msg) return 1, 2, 3, ['hello'], {'age' : 18} a = test_02() print(a) # (1, 2, 3, ['hello'], {'age': 18})
def logger(n): with open('日志记录', 'a') as f: # 重复代码 f.write('end action %s\n' % n) def action_1(n): print('action_1') logger(n) # with open('日志记录', 'a') as f: # 重复代码 # f.write('end action %s\n' % n) def action_2(n): print('action_2') logger(n) # with open('日志记录', 'a') as f: # f.write('end action %s\n' % n) def action_3(n): print('action_3') logger(n) # with open('日志记录', 'a') as f: # f.write('end action %s\n' % n) action_1(1) action_2(2) action_3(3)
拓展日志加时间功能
import time def logger(n): time_format = '%Y-%m-%d %X' t_current = time.strftime(time_format) with open('日志记录', 'a') as f: # 重复代码 f.write('%s end action %s\n' %(t_current, n)) def action_1(n): print('action_1') logger(n) # with open('日志记录', 'a') as f: # 重复代码 # f.write('end action %s\n' % n) def action_2(n): print('action_2') logger(n) # with open('日志记录', 'a') as f: # f.write('end action %s\n' % n) def action_3(n): print('action_3') logger(n) # with open('日志记录', 'a') as f: # f.write('end action %s\n' % n) action_1(1) action_2(2) action_3(3)
参数传递
在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="Runoob"
以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数
1.加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
2.加了两个星号 ** 的参数会以字典的形式导入,存放命名的变量参数。
#!/usr/bin/python3 def test(x,*args): print(x) print(args) print(args[0]) #test(5) test(5, 6, 7, 8, 8)
输出:
5
(6, 7, 8, 8)
6
#!/usr/bin/python3 def test(x,*kargs): print(x) print(kargs) print(kargs[0]) #test(5) test(5, *{'a':6, 'b':7, 'c':8})
输出:
5
('a', 'b', 'c')
a
#!/usr/bin/python3 def test(x,**kargs): print(x) print(kargs) #test(5) test(5, **{'a':7, 'b':9}) test(5, a=7, b=9)
输出:
5
{'a': 7, 'b': 9}
5
{'a': 7, 'b': 9}
def info(name, age, **kargs): print('%s, %d' %(name, age)) for item in kargs: print(kargs[item]) info('mike', 39) info(age=39, name='zhangsan',job='IT',hobby='basketball') ''' mike, 39 zhangsan, 39 IT basketball '''
def info(name, age, **kargs): print('%s, %d' %(name, age)) print(kargs) for item in kargs: print('%s: %s' %(item, kargs[item])) info('mike', 39) info(age=39, name='zhangsan',job='IT',hobby='basketball') ''' mike, 39 {} zhangsan, 39 {'job': 'IT', 'hobby': 'basketball'} job: IT hobby: basketball '''
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
规范:全局变量用大写,局部变量用小写
#!/usr/bin/python3 NAME = 'hello' def test(): print(NAME) def test1(): NAME = 'world' # 局部变量 print(NAME) def test2(): global NAME NAME = 'world' # 修改全局变量 print(NAME) test() test1() test2() print(NAME)
输出:
hello
world
world
world
#!/usr/bin/python3 def outer(): num = 100 print('outer:',num) def innner(): #num = 50 报错 #print('inner:',num) nonlocal num print('nonlocal:',num) num = 60 print('change nonlocal:',num) innner() print('outer:',num) outer()
输出:
outer: 100
nonlocal: 100
change nonlocal: 60
outer: 60
默认参数
#!/usr/bin/python3 def outer(x, y=100): print(x, y) outer(1) outer(1, 60)
输出:
1 100
1 60
关键字参数
def info(name, age): print('%s, %d' %(name, age)) info('mike', 39) # 位置参数 info(age=39, name='zhangsan') # 关键字参数
return返回值
def add(*args): sum = 0 for i in args: sum += i return sum print(add(1,5)) def show(*args): return 1,2,3,['hello','world',7] # 返回多个值得时候,以元祖的形式返回 print(show()) ''' 6 (1, 2, 3, ['hello', 'world', 7]) '''
函数作用域:
python中函数作用域分4中情况:
L: local,局部作用域
E: enclosing,嵌套的父级函数作用域,即包含此函数的上级函数的局部作用域,但不是全局的
G:global,全局变量,即模块级别定义的变量
B:build-in,系统固定模块里面的变量,比如:int,bytearray
搜索变量的顺序就是L > E > G > B
x = int(2.9) # build-in def outer(): o_count = 1 # enclosing def inner(): i_count = 2 # local print(o_count) inner() outer()
NAME = 'Python' def fun(): print(NAME) def fun1(): name = 'Linux' print(name) def fun2(): name = 'Windows' print(name) return fun2 return fun1 print(fun) # fun的地址 res = fun() print(res)# fun1的地址 res2 = res() print(res2) # # fun2的地址 res2() fun()()()
输出:
<function fun at 0x00000287CD5A5B70> Python <function fun.<locals>.fun1 at 0x00000287CD5A5C80> Linux <function fun.<locals>.fun1.<locals>.fun2 at 0x00000287CD5A5BF8> Windows Python Linux Windows
匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
lambda [arg1 [,arg2,.....argn]]:
#!/usr/bin/python3 sum = lambda arg1, arg2: arg1 + arg2 print(sum(1, 2))
# 匿名函数 print(lambda x : x + 1) #<function <lambda> at 0x0000022AE9245D90> f1 = lambda name : name + 'hello' res = f1('Mike') print(res) # Mikehello f2 = lambda x, y, z : (x + 1, y + 1, z + 1) print(f2(1,2,3)) # (2, 3, 4)