函数(八)-函数和匿名函数

计算机函数: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)

 

posted @ 2019-02-15 23:08  狂奔~  阅读(300)  评论(0编辑  收藏  举报