• Python学习笔记——函数


    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # 函数的作用:
        # 1.代码重用
        # 2.流程分解
    
    
    # 例1:函数的定义和调用
        def bar():
            print('hello world')
        bar()
        
    # 例2:函数参数
        2.1 形参与实参
            def add(x,y):  #x,y是形参
                print (x+y)
            add(3,5)        #3,5是实参
        2.2参数顺序
            def  people(name,age):
                print ('Name:',name)
                print ('Age:',age)
            people('Tom',23) #参数的传入是有顺序的。形参与实参的顺序要一一对应
        2.3关键字参数
            def  people(name,age):
                print ('Name:',name)
                print ('Age:',age)
            people(age=12,name='Bob')
        2.4默认参数
            def  people(name,age,sex='boy'):
                print ('Name:',name)
                print ('Age:',age)
                print ('Sex:',sex)
            people('Tom',23)
        2.4不定长参数
            >>> def bar(*arg):
            ...     print(arg)
            ...
            >>> bar(1,2,3)
            (1, 2, 3)
        2.5**kwargs 接收键值对参数
            >>> def bar(**kwargs):
            ...     print (kwargs)
            ...
            >>> bar(name='Tom',age=18)
            {'name': 'Tom', 'age': 18}
            
        2.6参数的位置
            >>> def bar(name,age,sex='boy',*args,**kwargs):
            ...     print(name,age,sex,args,kwargs)    
            Tom 18 1 (2, 3, 4) {'city': "xi'an"}
            >>> bar('Tom',18,1,2,3,4,city="xi'an")
            Tom 18 1 (2, 3, 4) {'city': "xi'an"}
            >>> bar('Tom',18,'boy',1,2,3,4,city="xi'an")
            Tom 18 boy (1, 2, 3, 4) {'city': "xi'an"}
            
    # 例3:函数的多态
        def add(x,y):
            print (x+y)
    
        add(3,5)
        add('hello','world')
    
    # 例4:嵌套函数
        def bar():
            def foo():
                print("hello world")
            foo()
        bar()
    
    # 例5:作用域法则LEGB
        # L-Local(function);函数内的名字空间
        # E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)
        # G-Global(module);函数定义所在模块(文件)的名字空间
        # B-Builtin(Python);Python内置模块的名字空间
    
    # 例6:global语句
        x = 88
        def bar():
            global x
            x = 99
        bar()
        print (x)
    
    # 例7:nonlocal ————用于嵌套函数中
        def bar():
            x = 1
            def foo():
                nonlocal x
                x += 1
            foo()
            print(x)
    
        bar()
    
    
    # 例8:闭包(closure):在一个内部函数对在外部的作用的作用域进行一个引用,那么内部函数就是一个闭包
    
        >>> def maker(N):
        ...     def action(X):    #一个内部函数
        ...             return X ** N  #N为上级函数的一个变量
        ...     return action
        ...
        >>> f = maker(2)
        >>> f
        <function maker.<locals>.action at 0x000002C47A1E2A60>
        >>> f(3)
        
        闭包的三个特点:
            1.闭包函数必须有内嵌函数
            2.内嵌函数需要引用该嵌套函数上一级namespace中的变量
            3.闭包函数必须返回内嵌函数
    # 例9:函数的返回值
        9.1 默认返回None
            >>> def bar():
            ...     print ("hello")
            ...
            >>> f = bar()
            hello
            >>> print(f)
            None
        
        9.2 指定返回值
            >>> def bar():
            ...     print("hello")
            ...     return 1
            ...
            >>> f = bar()
            hello
            >>> print(f)
            1
        9.3    返回计算结果
            >>> def bar(x,y):
            ...     return x + y
            ...
            >>> f = bar(1,2)
            >>> print(f)
            3
        9.4 结束函数
            >>> def bar():
            ...     print("hello")
            ...     return 1
            ...     print("world")
            >>> bar()
            hello
            1
        9.5 返回元组
            >>> def bar(x,y):
            ...     return x,y
            ...
            >>> bar(1,2)
            (1, 2)
        return的作用:
            1.结束函数
            2.返回某个对象
            
    # 例10:三元函数
        >>> print('hello') if True else False
        hello    
        
    # 例11:高阶函数
    
        11.1 变量名可以指向函数
            >>> abs(-10)
            10
            >>> f = abs
            >>> f(-10)
            10
        11.2 函数名可以作为其他函数的参数    
            >>> def bar(x,y,f):
            ...     return f(x)+f(y)
            ...
            >>> bar(-5,-3,abs)
            8
        11.3 函数名可以作为返回值
            >>> def bar():
            ...     def foo():
            ...         return "hello"
            ...     return foo
            ...
            >>> bar()
            <function bar.<locals>.foo at 0x00000194EED32A60>
        
    # 例12:装饰器(Decorator):1.在代码运行期间增加功能;2.不改变源代码
            1.在运行期间增加新功能
            def hello():
                print("hello")
    
            def show_time(func):
                print("------------")
                func()
                print("------------")
    
            show_time(hello)
            # 或者如下
            # hello = show_time(hello)
            # hello
            # 但调用方式还是发生了改变
            但是这样改变个源函数的调用方式
            2.让hello接收函数名
            #如果把一个函数名赋值给hello,hello()就可以执行函数了,
            #关键问题是如何让show_time(hello)作为函数名赋值给hello
            #想想高阶函数中函数名可以作为返回值返回的特性
            #可以吧上述的函数改为如下
            def hello():
                print("hello")
    
            def show_time(func):
                def inner():
                    print("------------")
                    func()
                    print("------------")
                return inner    #此时如果调用show_time,返回的就是inner函数的函数名
                
            hello=show_time(hello) #将inner函数赋值给hello
            hello()  #实际执行的是inner函数
            3.@bar
            #在python中hello=show_time(hello)可以写为@show_time,如下:    
            def show_time(func):
                def inner():
                    print("------------")
                    func()
                    print("------------")
                return inner
    
            @show_time
            def hello():
                print("hello")
                
            hello()
            4.装饰器的参数
            def show_time(func):
                def inner(name):
                    print("------------")
                    func(name)
                    print("------------")
                return inner
    
            @show_time
            def hello(name):
                print("hello",name)
    
            hello('Bob')
            5.函数中嵌套装饰器
            import time
            def logger(flag=''):
                def show_time(func):
                    def inner(*args,**kwargs):
                        start = time.time()
                        time.sleep(1)
                        func(*args,**kwargs)
                        end = time.time()
                        print('running time:',end - start)
                        if flag == 'true':
                            print('this is loggger')
                    return inner
                return show_time
    
            @logger('true')
            def foo(*args,**kwargs):
                sums = 0
                for i in args:
                    sums += i
                print(sums)
    
            @logger()
            def bar():
                print('bar..')
                
            foo(1,2,3)
            bar()
            6.6 源函数名称的问题————functools.wraps的作用
            def show_time(func):
                def inner(name):
                    print("------------")
                    func(name)
                    print("------------")
                return inner
    
            @show_time
            def hello(name):
                print("hello",name)
    
            print(hello.__name__)
    
            >>inner        
            源函数的名称变成了inner,不是原来的hello,通过引入wraps解决这个问题
            改进如下:
                from functools import wraps
    
                def show_time(func):
                    @wraps(func)
                    def inner(name):
                        print("------------")
                        func(name)
                        print("------------")
                    return inner
    
                @show_time
                def hello(name):
                    print("hello",name)
    
                print(hello.__name__)
    
                >>hello        
            6.7装饰器实例
            import sys
            from functools import wraps
            USERNAME, PASSWORD = 'root','123'
            no_login = True
            def login(func):
                @wraps(func)
                def inner(*args,**kwargs):
                    global no_login
                    if no_login:
                        print('您还没有登录,请登录---')
                        username = input('username:').strip()
                        password = input('password:').strip()
                        if USERNAME == username and PASSWORD == password:
                            no_login = False
                        else:
                            print('user or password is wrong !')
                            sys.exit()
                    func(*args, **kwargs)
                return inner
    
            @login
            def home():
                print('恭喜来到京东主页')
            @login
            def phone():
                print('这里是手机专卖')
            @login
            def book():
                print('这里是图书商店')
    
            main = """
            1.home
            2.phone
            3.book
            请选择要进入的主页
            """
            while True:
                print(main)
                choice = input(">>:").strip()
                if  choice == '1':
                    home()
                elif choice == '2':
                    phone()
                elif choice == '3':
                    book()
                else:
                    sys.exit()    
            
            总结:装饰器三要素:LEGB、高阶函数、闭包
    
        
  • 相关阅读:
    定时机制
    选择排序
    二分插入排序
    无名管道pipe
    Makefile
    Python下划线与命名规范
    Django IDE 开发环境的搭建
    Apache如何添加虚拟目录
    在Eclipse下如何安装插件
    Python的模块、包等概念的理解
  • 原文地址:https://www.cnblogs.com/gaoyuanzhi/p/9088338.html
Copyright © 2020-2023  润新知