• Python函数知识点总结


    1.函数的定义
    2.如何定义一个函数以及函数语法
    3.函数的调用
    4.函数的参数(形参,实参)以及参数的传递
    5.函数的返回值
    6.变量的作用域
    7.匿名函数
    8.嵌套函数和闭包
    9.装饰器
    10.函数思维导图

     

    1.函数的定义

    函数是组织好的,可重复使用的,用来实现一定功能的代码段。
    函数能提高应用的模块性,和代码的重复利用率。

    2.如何定义一个函数以及函数语法

    函数代码块以def关键词开头,后接函数名称和圆括号()
    传入的任何参数和自变量放在圆括号()中间
    函数的内容以冒号起始,并且缩进
    函数的第一行语句可以选择性的使用文档字符串————用于存放函数说明
    return 【表达式】结束函数,选择性的返回一个值给调用方。不带表达式的return相当于返回None
    语法:

    def function_name(parameters):
        '''函数说明'''
        function_suite
        return [expression]

    实例:

    def print_test(str_par):
        '''打印输入的字符串到标准显示设备上'''
        print(str_par)
        return
    print_test(test_success)

    3.函数的调用

    定义一个函数只给了函数一个名称,指定了函数里包含的参数和代码块结构。
    这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。
    实例:

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    #定义函数
    def print_test(str_par):
        '''打印输入的字符串到标准显示设备上'''
        print(str_par)
        return
    
    #调用函数
    print_test(test_success)

    4.函数的参数(形参,实参)以及参数的传递

    在python中,类型属于对象,变量是没有类型的。
    a = [1,2,3]
    a = "hello,world"
    以上代码中,[1,2,3]是list类型,"hello world"是string类型,而变量a是没有类型,她仅仅是一个对象的引用(一个指针),可以是list类型对象,也可以指定string类型对象

    可更改(mutable)和不可更改(immutable)对象
    在python中,string,tuple,number是不可更改的对象,而list,dict等则是可以修改的对象。
    1.不可变类型:变量赋值a = 5后在赋值a = 10,这里实际是新生成一个int值对象10,在让a指向它,而5被丢弃,不是改变a的值,相当于新生成了a。
    2.可变类型:变量赋值list_a = [1,2,3,4]后在赋值list_a[2] = 5则是将list list_a的第三个元素值更改,本身list_a没有动,只是其内部的一部分值被修改了。

    python函数的参数传递:
    1.不可变类型:如整数、字符串、元祖。如fun(a),传递的只是a的值,没有影响a对象本身。比如在fun(a)内部修改a的值,只是修改另一个复制的对象,不会影响a本身。
    2.可变类型:如列表,字典。如fun(list_a),则是将list_a真正的传过去,修改后fun外部的list_a也会受影响。

    python中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

    python传不可变对象实例:

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    def ChangeInt(a):
        a = 10
    
    b = 2
    ChangeInt(b)
    print(b)  #结果是2

    实例中有int对象2,指向它的变量是b,在传递给ChangeInt函数时,按传值的方式复制了变量b,a 和b都指向了同一个int对象,在a = 10时,则新生成一个int值对象10,并让a指向它。


    传可变对象实例

    #!/usr/bin/python
    #-*- encoding:UTF-8 -*-
    
    def ChangeList(mylist):
        "修改传入的列表“
        mylist.append([1,2,3,4]);
        print('函数内部取值:’,mylist)
        return
    
    #调用Changelist函数
    mylist = [10,20,30]
    ChangeList(mylist)
    print('函数外取值:‘,mylist)

    实例中传入函数的和在末尾添加新内容的对象用的是同一个引用,故输出结果如下:

    函数内取值:[10,20,30,[1,2,3,4]]
    函数外取值:[10,20,30,[1,2,3,4]]

    实参和形参
    形参:定义函数时接收的参数
    形参类型:位置参数,动态*args参数,默认参数,动态**kwargs参数

    位置参数:位置参数必须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

    调用test()函数时,你必选传入一个参数,不然会出现语法错误:

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
     
    
    def test( a ):
       "打印任何传入的字符串"
       print(a);
       return;
     
    #调用test函数
    test();
    以上实例输出结果:
    Traceback (most recent call last):
      File "test.py", line 11, in <module>
        printme();
    TypeError: printme() takes exactly 1 argument (0 given)

    关键字参数:
    关键字参数和函数调用关系紧密,函数调用使用关键字参数来确认传入的参数值。
    使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为python解释器能够用参数名匹配参数值。
    以下实例在函数test()调用时使用参数名:

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    
    def test(a ,b ):
        print(a)
        rerurn
    print(test(a = 2,b = 2)

    默认参数:
    调用函数时,默认参数的值如果没有传入,则被认为是默认值。下列会打印默认的age,即是没有传入age的参数:

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    def test(name,age = 20):
        print(name,age)
        return
    test(age = 22,name = jack)
    test(name = jack)

    动态参数:
    你可能需要一个函数能够处理比当初生命是更多的参数。这些参数叫做不定长参数
    语法如下:

    def function_name(*args,**kwargs):
        function_suite
        return[expression]

    加了星号(*)的变量名会存放所有未命名的变量参数。返回为元祖数据类型
    加了两个星号(**)的变量名会存放所有关键字参数。返回为字典数据类型


    参数定义顺序:位置参数->*args->默认参数->**kwargs

    实参:函数调用时传递的参数
    实参类型:位置参数,关键字参数
    位置参数:必须和函数定义时的参数一对一对应
    关键字参数:可以通过*[],*()一次性传递多个参数给*args;通过**{}一次性传递多个参数给**kwargs参数

    5.函数的返回值

    return语句【表达式】退出函数(结束一个函数的执行),选择性地向调用方返回一个表达式。
    返回值可以是任意数据类型
    返回值情况:
    1,返回值为None的情况
    当不写return时,默认返回值为None
    return不加参数时,返回None
    2,返回值不为None的情况
    返回一个值: return xxx 返回一个值(一个变量) 任意数据类型
    返回多个值: return a,b,[1,2,3] ; 用一个变量接收时返回的是一个元祖,也可以用相应数量的变量去接收

    6.变量的作用域

    一个程序的所有变量并不是在哪个位置都可以访问的。访问权限决定于这个变量实在哪里赋值的。
    命名空间:
    局部命名空间
    全局命名空间
    内置命名空间

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    total = 0 # 这是一个全局变量
    def sum(arg1,arg2):
        '''返回2个参数的和'''
        total1 = arg1 + arg2   #total在这里局部变量
        print('函数内是局部变量:',total)
        return(total)
    #调用sum函数
    sum(10,20);
    print('函数外是全局变量:’,total)
    
    #输入结果
    函数内是局部变量:30
    函数外是全局变量:0

    变量查找顺序:先查找全局作用域,然后内置作用域
    global关键字:可以是在函数内部声明的变量变成全局变量
    nonlocal关键字:可以让内部函数中的变量在上一层函数中生效,外部必须要有这个变量

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    globvar = 0
    
    def set_globvar_to_one():
        global globvar    # 使用 global 声明全局变量
        globvar = 1
    
    def print_globvar():
        print(globvar)     # 没有使用 global
    
    set_globvar_to_one()
    print  globvar        # 输出 1
    print_globvar()       # 输出 1,函数内的 globvar 已经是全局变量

    7.匿名函数

    python使用lambda来创建匿名函数。
    1.lambda只是一个表达式,函数体比def简单很多。
    2.lambda的主题式一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
    3.lambda函数拥有自己的命名空间,且不能访问只有参数列表之外或全局命名空间里的参数
    4.虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率

    语法:lambda函数的语法只能包含一个语句,如下:

    lambda[arg1[,arg2,......argn]]:expression
    
    如下实例:
    #!/usr/bin/python
    #-*- coding:UTF-8 -*-
    sum = lambda arg1,arg2:arg1 + arg2;
    print('相加后的值为:‘,sum(10,20)
    print('相加后的值为:‘,sum(20,20)
    
    以上实例输出结果:
    相加后的值为:30
    相加后的值为:40

    8.嵌套函数和闭包

    在一个函数内部定义函数就创建了嵌套函数,如下所示:

    def outer():
        outer_var = 'outer variable'
        def inner():
            return outer_var
        return innter

    在这种类型的函数定义中,函数inner只在函数outer内部有效,所以当内部函数需要被返回(移动到外部作用范围)或被传递给另一个函数时,使用嵌套函数通常比较方便。在如在上面的嵌套函数中,每次调用外部函数时都会创建一个新的嵌套函数实例,这是因为,在每次执行外部函数时,都会执行一次内部函数定义,而其函数体则不会被执行。

    嵌套函数可以访问创建它的环境,这是python函数定义语句的直接结果。一个结果是,外部函数中定义的变量可以在内部函数用引用,即是外部函数已经执行结束。

    ef outer():
        outer_var = "outer variable"
        def inner():
            return outer_var
        return inner
     
    >>> x = outer()
    >>> x
    <function inner at 0x0273BCF0>
    >>> x()
    'outer variable'

    当内部嵌套的函数引用外部函数中的变量时,我们说嵌套函数相对于引用变量时封闭的。我们可以使用函数对象的一个特殊属性’_closure_‘来访问这个封闭的变量,如下所示:

    >>>cl = x.__closure__
    >>>cl
    (<cell at 0x029E4470:str object at 0x02A0FD90,)
    >>>cl[0].cell_contents
    'outer variable'

    python中的闭包有一个古怪的行为。在python2.x以及更低版本中,指向不可变类型(例如字符串和数字)的变量不能再闭包内反弹。

    def counter():
        count = 0
        def c():
            count += 1
            return count
        return c
     
    >>> c = counter()
    >>> c()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 4, in c
    UnboundLocalError: local variable 'count' referenced before assignment

    一个相当不可靠的解决方案是,使用一个可变类型来捕获闭包,如下所示:

    def counter():
        count = [0]
        def c():
            count[0] += 1
            return count[0]
        return c
     
    >>> c = counter()
    >>> c()
    1
    >>> c()
    2
    >>> c()
    3

    python3引入了nonlocal关键字用来解决下面所示的闭包范围问题。

    def counter():
           count = 0
           def c():
               nonlocal count
               count += 1
               return count
            return c

    闭包可以用来维持状态(与类的作用不同),在一些简单的情况下,还可以提供一种简洁性与可读性比类更强的解决方案

    9.装饰器

    装饰器的本质:是一个闭包函数
    装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

    装饰器结构:

    import time
    def timer(func):
        def inner():
            start = time.time()
            func()
            print(time.time() - start)
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1():
        print('in func1')
    
    
    func1()

    带参数的装饰器:

    def timer(func):
        def inner(a):
            start = time.time()
            func(a)
            print(time.time() - start)
        return inner
    
    @timer
    def func1(a):
        print(a)
    
    func1(1)

    带多个参数的装饰器:

    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func1 = timer(func1)
    def func1(a,b):
        print('in func1')
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func1('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))

    带返回值的装饰器:

    import time
    def timer(func):
        def inner(*args,**kwargs):
            start = time.time()
            re = func(*args,**kwargs)
            print(time.time() - start)
            return re
        return inner
    
    @timer   #==> func2 = timer(func2)
    def func2(a):
        print('in func2 and get a:%s'%(a))
        return 'fun2 over'
    
    func2('aaaaaa','bbbbbb')
    print(func2('aaaaaa'))

    多个装饰器装饰一个函数:

    def wrapper1(func):
        def inner():
            print('wrapper1 ,before func')
            func()
            print('wrapper1 ,after func')
        return inner
    
    def wrapper2(func):
        def inner():
            print('wrapper2 ,before func')
            func()
            print('wrapper2 ,after func')
        return inner
    
    @wrapper1     #f = wrapper1(f) ---> wrapper1(wrapper2(f)
    @wrapper2     #f = wrapper2(f)
    def f():
        print('in f')
    f()

    执行结果:
    wrapper1 ,before func
    wrapper2 ,before func
    in f
    wrapper2 ,after func
    wrapper1 ,after func

    带参数的装饰器:

    F = True          #stpe1 装饰器的开关变量
    def outer(flag):  #step 2
        def wrapper(func): #step 4
            def inner(*args,**kwargs): #stpe 6
                if flag:               #step 9
                    print('before')   #step 10
                    ret = func(*args,**kwargs)  #step 11  执行原函数
                    print('after')             #step13
                else:
                    ret = func(*args,**kwargs)
                    print('123')
                return ret                     #step 14
            return inner    #step 7
        return wrapper     #step 5
    
    @outer(F)   #先执行step 3 :outer(True)这个函数,然后step 6:@wrapper   #此处把开关参数传递给装饰器函数
    def hahaha():
        pass    #step 12
    hahaha()    # step 8    相当于inner()

    10.函数思维导图

  • 相关阅读:
    修改spring boot 的banner
    创建oracle 数据库的时候 提示 “使用database control配置数据库时,要求在当前oracle主目录中配置监听程序”
    Spring Boot 中文乱码解决
    SharePoint 2013 安装图解
    Hadoop 数据安全方案 Apache Eagle
    通用财经数据传输与监控平台1.0(泛型,接口与基类,Sql,Ibatis,Awt,Swing)
    应用Druid监控SQL语句的执行情况
    监控和剖析数据库操作 -- P6Spy、SQL Profiler、IronTrack SQL 使用简介
    Jboss7集群配置说明
    JavaMelody监控SQL
  • 原文地址:https://www.cnblogs.com/eric_yi/p/7256520.html
Copyright © 2020-2023  润新知