zoukankan      html  css  js  c++  java
  • Python-06-函数

    一、函数的定义

    函数是第一类对象,即函数可以当作数据传递

    #1 可以被引用
    #2 可以当作参数传递
    #3 返回值可以是函数
    #3 可以当作容器类型的元素

    1. 定义方式

    def 函数名(参数1,参数2,参数3,...):
        '''注释'''
        函数体
        return 返回的值

    2. 函数的返回值

      无return->None

      return1个值->返回1个值

      return 逗号分隔多个值->元组

    二、函数的调用

    1. 调用的方法

    函数的调用:函数名加括号

    • 先找到名字
    • 根据名字调用代码

    2. 先定义,再调用

    函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名
    #测试一
    def foo():
        print('from foo')
        bar()
    foo() #报错
    
    #测试二
    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()
    def bar():
        print('from bar')
    #调用阶段
    foo()
    

     三、函数的参数

    1. 位置参数

    按照从左到右的顺序定义的参数

      位置形参:必选参数

      位置实参:按照位置给形参传值

    2、关键字参数

    按照key=value的形式定义的实参无需按照位置为形参传值 ,

    注意的问题:

      1. 关键字实参必须在位置实参右面

      2. 对同一个形参不能重复传值

    3、默认参数

    形参在定义时就已经为其赋值可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参

    注意的问题:

      1. 只在定义时赋值一次

      2. 默认参数的定义应该在位置形参右面

      3. 默认参数通常应该定义成不可变类型

    4. 可变长参数

    可变长指的是实参值的个数不固定, 而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs

    def test(x, *args, **kwargs):
        print(x)
        print(args)
        print(kwargs)    
    test(1, *[2, 3, 4, 5], **{'y': 2, 'z': 3})
    
    运行结果:
    1
    (2, 3, 4, 5)
    {'y': 2, 'z': 3}
    
    def test(x, *args, **kwargs):
        print(x)
        print(args)
        print(kwargs)
    test(1, 2, 3, 4, 5, y=2, z=3)
    
    运行结果:
    1
    (2, 3, 4, 5)
    {'y': 2, 'z': 3}
    

     四、全局变量和局部变量

    顶头写的是全局变量

    函数内部的是局部变量

    global指定全局变量

    nonlocal指定上一级的变量

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

     五、风湿理论(函数即变量)

    # def foo():
    #     print('from foo')
    #     bar()
    #
    # foo()
    # 报错
    
    # 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 bar():
    #     print('from bar')
    # 报错
    

     六、递归

    1. 定义

    如果一个函数在内部调用自身本身,这个函数就是递归函数

    def calc(n):
        print(n)
        if n // 2 == 0:
            return
        return calc(n / 2)
    calc(10)
    
    10
    5.0
    2.5
    1.25
    

    递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

    使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

    七、函数的作用域

    1. 作用域即范围

      - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
        - 局部范围(局部名称空间属于该范围):临时存活,局部有效

    2. 作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

    x=1
    def f1():
        def f2():
            print(x)
        return f2
    x=100
    def f3(func):
        x=2
        func()
    x=10000
    f3(f1())
    

    3. 查看作用域:globals(),locals()

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
    locals 是函数内的名字空间,包括局部变量和形参
    enclosing 外部嵌套函数的名字空间(闭包中常见)
    globals 全局变量,函数定义所在模块的名字空间
    builtins 内置模块的名字空间

    八、匿名函数

    匿名函数lambda x: x * x实际上就是:

    def f(x):
        return x * x
    

    关键字lambda表示匿名函数,冒号前面的x表示函数参数。

    匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

    用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

    >>> f = lambda x: x * x
    >>> f
    <function <lambda> at 0x101c6ef28>
    >>> f(5)
    25
    

    同样,也可以把匿名函数作为返回值返回,比如:

    def build(x, y):
        return lambda: x * x + y * y
    
  • 相关阅读:
    图与图算法在实际中的应用
    python Tricks —— list 镜像复制与 list comprehension 列表解析的顺序
    C语言高速入门系列(五)
    Linked List Cycle
    poj 2689 Prime Distance(大区间筛素数)
    三层结构——理论篇
    史上最简单的Hibernate入门简单介绍
    [SQL]远程使用PostgreSQL Studio可视化查看PostgreSQL数据库
    MySQL建立双向主备复制server配置方法
    win2003的IIS無法使用,又一次安裝提示找不到iisadmin.mfl文件
  • 原文地址:https://www.cnblogs.com/lsf123456/p/11150750.html
Copyright © 2011-2022 走看看