zoukankan      html  css  js  c++  java
  • 函数

    一、函数定义方法:

    def fuc_name(value):    #fuc_name函数名,value为参数可以为多个,也可以没有参数
        "the function definition" #函数描述
        value+=1     #代码块
        return value    

    #定义返回值:
    若返回值=0,返回None
    若返回值=1,返回object
    若返回值>1,返回tuple
    def test01():
        msg = 'test01'
        print(msg)
    
    
    def test02():
        msg = 'test02'
        print(msg)
        return msg
    
    def test03():
        msg = 'test03'
        print(msg)
        return 1,2,3,4,'a',['alex'],{'name':'alex'},None
    
    def test04():
        msg = 'test03'
        print(msg)
        return {'name':'alex'}
    t1=test01()
    t2=test02()
    t3=test03()
    t4=test04()
    print(t1)
    print(t2)
    print(t3)
    print(t4)

     如果函数的返回值是一个函数名,则返回函数地址

    def test1():
        print('in the test1')
    
    
    def test():
        print('in the test')
        return test1
    
    
    # print(test)
    res = test()
    print(res)
    print(res())  # test1()
    '''
    result:
    in the test
    <function test1 at 0x008D92B0>
    in the test1
    '''

    如果函数的返回值是一个func(),则运行完func后,再返回func的return

    def bar():
        print('from bar')
    
    
    def foo():
        print('from foo')
        return bar()
    
    
    n = foo()
    print(n)
    '''
    result:
    from foo
    from bar
    None
    '''

    二、参数

    1、形参只有在调用的时候才占内存

    2、位置参数和关键字参数:

      位置参数必须一一对应,缺一不行,多一也不行

      关键字参数不必一一对应,缺一不行,多一也不行

      混合使用时,关键字参数在位置参数右边

    3、默认参数

    def handle(x,type='mysql'):
        print(x)
        print(type)
    handle('hello')
    handle('hello',type='sqlite')
    handle('hello','sqlite')

    4、参数组 :**字典 *列表

    ①*args

    def test(x,*args):
        print(x)
        print(args)
    
    
    test(1)    #args=()
    test(1,2,3,4,5)    #args=(2,3,4,5)
    test(1,{'name':'alex'})    #args=({'name': 'alex'},)
    test(1,['x','y','z'])    #args=(['x', 'y', 'z'],),以一个整体传入
    test(1,*['x','y','z'])    #args=('x', 'y', 'z'),按遍历方式传入
    test(1,*('x','y','z'))    #args=('x', 'y', 'z')

    ②**kwargs

    def test(x,**kwargs):
        print(x)
        print(kwargs)
    test(1,y=2,z=3) #kwargs={'y': 2, 'z': 3}
    test(1,1,2,2,2,2,2,y=2,z=3)#会报错
    test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值

    ③*args,**kwargs

    def test(x, *args, **kwargs):
        print(x)
        print(args, args[-1])
        print(kwargs, kwargs.get('y'))
    
    
    test(1,1,2,1,1,11,1,x=1,y=2,z=3) #报错,由于x赋值两次
    test(1, 1, 2, 1, 1, 11, 1, y=2, z=3)
    '''
    args=(1, 2, 1, 1, 11, 1) args[-1]=1
    kwargs={'y': 2, 'z': 3} kwargs.get('y')=2
    '''
    test(1, *[1, 2, 3], **{'y': 1})
    '''
    args=(1, 2, 3) args[-1]=3
    kwargs={'y': 1} kwargs.get('y')=1
    '''

    三、局部变量与全局变量

    全局变量变量名大写
    局部变量变量名小写

    局部作用域里的变量定义不影响作用域外,

    如果函数中无global,调用时先在当前作用域中找,只能读取全局变量,不能重新赋值,

    但对于可变类型,可对内部元素进行操作

    name = "we"
    
    
    def ex():
        name = 123
        print(name)
    
    
    ex()  # 123
    print(name)  # we
    NAME = ["产品经理", "廖波湿"]
    
    
    def qupengfei():
        global NAME
        NAME.append('XXOO')
        print('我要搞', NAME)
    
    
    qupengfei()

    函数内定义的变量外部不能调用:

    name = "we"
    
    
    def ex():
        name1 = 123
        print(name1)
    
    
    ex()  # 123
    print(name1)  # 报错

    未调用函数之前,函数定义内的代码块不编译:

    NAME = "杠娘"
    
    
    def yangjian():
        # NAME = "史正文"
        global NAME
        NAME = "小东北"
        print('我要搞', NAME)
    
    
    def qupengfei():
        # NAME = "基"
        print('我要搞', NAME)
    
    
    qupengfei()
    yangjian()
    qupengfei()
    '''
    打印结果为:
    我要搞 杠娘
    我要搞 小东北
    我要搞 小东北
    '''

    如果要在函数中更改全局变量要使用global,变量本质上就是全局那个变量,可读取和赋值,global放在局部变量前

    name = "we"
    
    
    def ex():
        global name
        name = 123
        print(name)
    
    
    ex()  # 123
    print(name)  # 123

    四、函数的嵌套&调用与相对全局/局部变量

    函数执行顺序

    NAME = '海风'  # 第1步
    
    
    def huangwei():  # 第2步:将函数体写入内存,但不执行
        name = "黄伟"  # 第4步
        print(name)  # 第5步
    
        def liuyang():  # 第6步:将函数体写入内存,但不执行
            name = "刘洋"  # 第8步
            print(name)  # 第9步
    
            def nulige():  # 第10步:将函数体写入内存,但不执行
                name = '沪指花'  # 第13步
                print(name)  # 第14步
    
            print(name)  # 第11步
            nulige()  # 第12步
    
        liuyang()  # 第7步
        print(name)  # 第15步
    
    
    huangwei()  # 第3步
    '''
    运行结果:
    黄伟
    刘洋
    刘洋
    沪指花
    黄伟
    '''

    无论嵌套几层,global永远代指最外层的绝对全局变量:

    name = "刚娘"
    
    
    def weihou():
        name = "陈卓"
    
        def weiweihou():
            global name
            name = "冷静"
    
        weiweihou()
        print(name)
    
    
    print(name)
    weihou()
    print(name)
    '''
    执行结果:
    刚娘
    陈卓
    冷静
    '''

    nonlocal,指定上一级变量,如果没有就继续往上直到找到为止:

    name = "刚娘"
    
    
    def weihou():
        name = "陈卓"
    
        def weiweihou():
            nonlocal name  # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
            name = "冷静"
    
        print(name)
        weiweihou()
        print(name)
    
    
    print(name)
    weihou()
    print(name)
    '''
    result:
    刚娘
    陈卓
    冷静
    刚娘
    '''

    五、调用函数的向前引用:

    函数==变量

    1、调用函数前必须先定义函数

    2、代码从上到下阅读,读到就将内容写入内存

    正确示例:

    def bar():
        print('from bar')
    
    
    def foo():
        print('from foo')
        bar()
    
    
    foo()
    def foo():
        print('from foo')
        bar()
    
    
    def bar():
        print('from bar')
    
    
    foo()

    错误示例:

    def foo():
        print('from foo')
        bar()
    
    foo()
    def foo():
        print('from foo')
        bar()
    
    
    foo()
    
    
    def bar():
        print('from bar')

    六、递归

    1、必须有一个明确结束条件

    2、每进入一次递归,问题规模应比上一次减小

    3、递归效率不高,递归层数过多导致栈的溢出

    递归问路(可断点理清思路)

    person_list = ['alex', 'wupeiqi', 'linhaifeng', 'zsc']
    
    
    def ask_way(person_list):
        print('-' * 60)
        if len(person_list) == 0:
            return '根本没人知道'
        person = person_list.pop(0)
        if person == 'linhaifeng':
            return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' % person
        print('hi 美男[%s],敢问路在何方' % person)
        print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' % (person, person_list))
        res = ask_way(person_list)
        print('%s问的结果是: %s' % (person, res))
        return res
    
    
    res = ask_way(person_list)
    print(res)
    NAME = '海风'  # 第1步
    
    
    def huangwei():  # 第2步:将函数体写入内存,但不执行
    name = "黄伟"  # 第4步
    print(name)  # 第5步
    
    def liuyang():  # 第6步:将函数体写入内存,但不执行
    name = "刘洋"  # 第8步
    print(name)  # 第9步
    
    def nulige():  # 第10步:将函数体写入内存,但不执行
    name = '沪指花'  # 第13步
    print(name)  # 第14步
    
    print(name)  # 第11步
    nulige()  # 第12步
    
    liuyang()  # 第7步
    print(name)  # 第15步
    
    
    huangwei()  # 第3步
    '''
    运行结果:
    黄伟
    刘洋
    刘洋
    沪指花
    黄伟
    '''



    七、函数的作用域
    函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系
    注意:
      foo()()()的运行与结果
    name = 'alex'
    
    
    def foo():
        name = 'lhf'
    
        def bar():
            name = 'wupeiqi'
            print(name, 'in bar', sep=':')
    
            def tt():
                print(name, 'in tt', sep=':')
    
            return tt
    
        return bar
    
    
    r1 = foo()
    r2 = r1()  # tt
    r3 = r2()
    foo()()()
    '''
    result:
    wupeiqi:in bar
    wupeiqi:in tt
    wupeiqi:in bar
    wupeiqi:in tt
    '''

    八、匿名函数

    形式:

      lamda 形参:返回值

    直接打印匿名函数,返回值是函数地址

    print(lambda x: x + 1)
    '''
    result:
    <function <lambda> at 0x005D9268>
    '''

    单独调用匿名函数需要给匿名函数命名

    func = lambda x: x + 1
    print(func(10))
    '''
    result:
    11
    '''

    返回多个值时要加括号(元组)

    lambda x,y,z:(x+1,y+1,z+1)    #正常运行
    lambda x,y,z:x+1,y+1,z+1    #报错
    
    '''
    正常函数定义时,return值系统直接转换成元组
    '''
    def test(x,y,z):
        return x+1,y+1  #----->(x+1,y+1)

    九、函数式编程

    更多内容见:egon09.blog.51cto.com/9161406/1842475

    1、高阶函数:

      1、函数接收的参数是一个函数名

      2、返回值中包含函数名

    # 函数接收的参数是一个函数名
    def foo(n):  # n=bar
        print(n)
    
    
    def bar(name):
        print('my name is %s' % name)
    
    
    foo(bar('alex'))
    # 返回值中包含函数
    def bar():
        print('from bar')
    
    
    def foo():
        print('from foo')
        return bar
    
    
    n = foo()
    n()

    2、map函数

    num_l = [1, 2, 10, 5, 3, 7]
    # map示例
    res = map(lambda x: x + 1, num_l)
    print('内置函数map,处理结果', res)
    '''
    result:
    内置函数map,处理结果 <map object at 0x0055C190>
    '''
    for i in res:
        print(i)
    '''
    result:
    2
    3
    11
    6
    4
    8
    '''
    print(list(res))
    '''
    由于前面
    for i in res:
        print(i)
    所以这里的result:
    []
    
    如果没有
    for i in res:
        print(i)
    result:
    [2, 3, 11, 6, 4, 8]
    '''
    
    
    # 对map函数的理解
    
    def reduce_one(x):
        return x - 1
    
    
    def map_test(func, array):  # func=lambda x:x+1    arrary=[1,2,10,5,3,7]
        ret = []
        for i in array:
            res = func(i)  # add_one(i)
            ret.append(res)
        return ret
    
    
    print(map_test(lambda x: x + 1, num_l))
    '''
    result:
    [2, 3, 11, 6, 4, 8]
    '''
    
    print('传的是有名函数', list(map(reduce_one, num_l)))
    '''
    result:
    传的是有名函数 [0, 1, 9, 4, 2, 6]
    '''
    msg = 'linhaifeng'
    print(list(map(lambda x: x.upper(), msg)))
    '''
    result:
    ['L', 'I', 'N', 'H', 'A', 'I', 'F', 'E', 'N', 'G']
    '''

    3、filter函数

    # filter函数
    movie_people = ['alex_sb', 'wupeiqi_sb', 'linhaifeng', 'yuanhao_sb']
    print(filter(lambda n: not n.endswith('sb'), movie_people))
    # --><filter object at 0x00502FD0>
    res = filter(lambda n: not n.endswith('sb'), movie_people)
    print(list(res))
    # -->['linhaifeng']
    print(list(filter(lambda n: not n.endswith('sb'), movie_people)))
    # -->['linhaifeng']

    对filter函数的理解

    movie_people = ['alex_sb', 'wupeiqi_sb', 'linhaifeng', 'yuanhao_sb']
    
    
    def filter_test(func, array):
        ret = []
        for p in array:
            if not func(p):
                ret.append(p)
        return ret
    
    
    res = filter_test(lambda n: n.endswith('sb'), movie_people)
    print(res)
    # -->['linhaifeng']

    4、reduce函数

    python 3中调用reduce函数需要

    from functools import reduce
    from functools import reduce
    
    num_l = [1, 2, 3, 100]
    print(reduce(lambda x, y: x + y, num_l, 1))  # -->107
    
    print(reduce(lambda x, y: x + y, num_l))  # -->106

    对reduce函数的理解

    num_l = [1, 2, 3, 100]
    
    
    def reduce_test(func, array, init=None):
        if init is None:
            res = array.pop(0)
        else:
            res = init
        for num in array:
            res = func(res, num)
        return res
    
    
    print(reduce_test(lambda x, y: x + y, num_l, 1))  # -->107

    5、总结

    map()处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
    filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
    reduce:处理一个序列,然后把序列进行合并操作
    #filter()
    people=[
        {'name':'alex','age':1000},
        {'name':'wupei','age':10000},
        {'name':'yuanhao','age':9000},
        {'name':'linhaifeng','age':18},
    ]
    print(list(filter(lambda p:p['age']<=18,people)))
    #reduce
    from functools import reduce
    print(reduce(lambda x,y:x+y,range(100),100))
    print(reduce(lambda x,y:x+y,range(1,101)))

    十、内置函数

    详见https://docs.python.org/3/library/functions.html?highlight=built#ascii

  • 相关阅读:
    学校的破网,你别再掉了
    PhotoShop SDK的获取
    我的C++博客开张了
    一个新的嵌入式门户
    试用Bloglines.com
    PhotoShop的插件体系
    VB6 to VB.NET Migration Guide Community Preview #4
    看看Microsoft都买了些什么
    Borland CTO辞职
    PhotoShop插件的开发
  • 原文地址:https://www.cnblogs.com/jiangzhch5/p/13257982.html
Copyright © 2011-2022 走看看